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 #include "spdk_internal/thread.h" 40 41 #include "common/lib/ut_multithread.c" 42 #include "../bs_dev_common.c" 43 #include "blob/blobstore.c" 44 #include "blob/request.c" 45 #include "blob/zeroes.c" 46 #include "blob/blob_bs_dev.c" 47 48 struct spdk_blob_store *g_bs; 49 spdk_blob_id g_blobid; 50 struct spdk_blob *g_blob; 51 int g_bserrno; 52 struct spdk_xattr_names *g_names; 53 int g_done; 54 char *g_xattr_names[] = {"first", "second", "third"}; 55 char *g_xattr_values[] = {"one", "two", "three"}; 56 uint64_t g_ctx = 1729; 57 bool g_use_extent_table = false; 58 59 struct spdk_bs_super_block_ver1 { 60 uint8_t signature[8]; 61 uint32_t version; 62 uint32_t length; 63 uint32_t clean; /* If there was a clean shutdown, this is 1. */ 64 spdk_blob_id super_blob; 65 66 uint32_t cluster_size; /* In bytes */ 67 68 uint32_t used_page_mask_start; /* Offset from beginning of disk, in pages */ 69 uint32_t used_page_mask_len; /* Count, in pages */ 70 71 uint32_t used_cluster_mask_start; /* Offset from beginning of disk, in pages */ 72 uint32_t used_cluster_mask_len; /* Count, in pages */ 73 74 uint32_t md_start; /* Offset from beginning of disk, in pages */ 75 uint32_t md_len; /* Count, in pages */ 76 77 uint8_t reserved[4036]; 78 uint32_t crc; 79 } __attribute__((packed)); 80 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size"); 81 82 static void 83 _get_xattr_value(void *arg, const char *name, 84 const void **value, size_t *value_len) 85 { 86 uint64_t i; 87 88 SPDK_CU_ASSERT_FATAL(value_len != NULL); 89 SPDK_CU_ASSERT_FATAL(value != NULL); 90 CU_ASSERT(arg == &g_ctx); 91 92 for (i = 0; i < sizeof(g_xattr_names); i++) { 93 if (!strcmp(name, g_xattr_names[i])) { 94 *value_len = strlen(g_xattr_values[i]); 95 *value = g_xattr_values[i]; 96 break; 97 } 98 } 99 } 100 101 static void 102 _get_xattr_value_null(void *arg, const char *name, 103 const void **value, size_t *value_len) 104 { 105 SPDK_CU_ASSERT_FATAL(value_len != NULL); 106 SPDK_CU_ASSERT_FATAL(value != NULL); 107 CU_ASSERT(arg == NULL); 108 109 *value_len = 0; 110 *value = NULL; 111 } 112 113 static int 114 _get_snapshots_count(struct spdk_blob_store *bs) 115 { 116 struct spdk_blob_list *snapshot = NULL; 117 int count = 0; 118 119 TAILQ_FOREACH(snapshot, &bs->snapshots, link) { 120 count += 1; 121 } 122 123 return count; 124 } 125 126 static void 127 ut_spdk_blob_opts_init(struct spdk_blob_opts *opts) 128 { 129 spdk_blob_opts_init(opts); 130 opts->use_extent_table = g_use_extent_table; 131 } 132 133 static void 134 bs_op_complete(void *cb_arg, int bserrno) 135 { 136 g_bserrno = bserrno; 137 } 138 139 static void 140 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 141 int bserrno) 142 { 143 g_bs = bs; 144 g_bserrno = bserrno; 145 } 146 147 static void 148 blob_op_complete(void *cb_arg, int bserrno) 149 { 150 g_bserrno = bserrno; 151 } 152 153 static void 154 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 155 { 156 g_blobid = blobid; 157 g_bserrno = bserrno; 158 } 159 160 static void 161 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 162 { 163 g_blob = blb; 164 g_bserrno = bserrno; 165 } 166 167 static void 168 blob_init(void) 169 { 170 struct spdk_blob_store *bs; 171 struct spdk_bs_dev *dev; 172 173 dev = init_dev(); 174 175 /* should fail for an unsupported blocklen */ 176 dev->blocklen = 500; 177 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 178 poll_threads(); 179 CU_ASSERT(g_bserrno == -EINVAL); 180 181 dev = init_dev(); 182 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 183 poll_threads(); 184 CU_ASSERT(g_bserrno == 0); 185 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 186 bs = g_bs; 187 188 spdk_bs_unload(bs, bs_op_complete, NULL); 189 poll_threads(); 190 CU_ASSERT(g_bserrno == 0); 191 g_bs = NULL; 192 } 193 194 static void 195 blob_super(void) 196 { 197 struct spdk_blob_store *bs; 198 struct spdk_bs_dev *dev; 199 spdk_blob_id blobid; 200 struct spdk_blob_opts blob_opts; 201 202 dev = init_dev(); 203 204 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 205 poll_threads(); 206 CU_ASSERT(g_bserrno == 0); 207 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 208 bs = g_bs; 209 210 /* Get the super blob without having set one */ 211 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 212 poll_threads(); 213 CU_ASSERT(g_bserrno == -ENOENT); 214 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 215 216 /* Create a blob */ 217 ut_spdk_blob_opts_init(&blob_opts); 218 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 219 poll_threads(); 220 CU_ASSERT(g_bserrno == 0); 221 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 222 blobid = g_blobid; 223 224 /* Set the blob as the super blob */ 225 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 226 poll_threads(); 227 CU_ASSERT(g_bserrno == 0); 228 229 /* Get the super blob */ 230 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 231 poll_threads(); 232 CU_ASSERT(g_bserrno == 0); 233 CU_ASSERT(blobid == g_blobid); 234 235 spdk_bs_unload(bs, bs_op_complete, NULL); 236 poll_threads(); 237 CU_ASSERT(g_bserrno == 0); 238 g_bs = NULL; 239 } 240 241 static void 242 blob_open(void) 243 { 244 struct spdk_blob_store *bs; 245 struct spdk_bs_dev *dev; 246 struct spdk_blob *blob; 247 struct spdk_blob_opts blob_opts; 248 spdk_blob_id blobid, blobid2; 249 250 dev = init_dev(); 251 252 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 253 poll_threads(); 254 CU_ASSERT(g_bserrno == 0); 255 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 256 bs = g_bs; 257 258 ut_spdk_blob_opts_init(&blob_opts); 259 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 260 poll_threads(); 261 CU_ASSERT(g_bserrno == 0); 262 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 263 blobid = g_blobid; 264 265 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 266 poll_threads(); 267 CU_ASSERT(g_bserrno == 0); 268 CU_ASSERT(g_blob != NULL); 269 blob = g_blob; 270 271 blobid2 = spdk_blob_get_id(blob); 272 CU_ASSERT(blobid == blobid2); 273 274 /* Try to open file again. It should return success. */ 275 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 276 poll_threads(); 277 CU_ASSERT(g_bserrno == 0); 278 CU_ASSERT(blob == g_blob); 279 280 spdk_blob_close(blob, blob_op_complete, NULL); 281 poll_threads(); 282 CU_ASSERT(g_bserrno == 0); 283 284 /* 285 * Close the file a second time, releasing the second reference. This 286 * should succeed. 287 */ 288 blob = g_blob; 289 spdk_blob_close(blob, blob_op_complete, NULL); 290 poll_threads(); 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 poll_threads(); 299 CU_ASSERT(g_bserrno == 0); 300 CU_ASSERT(g_blob != NULL); 301 blob = g_blob; 302 303 spdk_blob_close(blob, blob_op_complete, NULL); 304 poll_threads(); 305 CU_ASSERT(g_bserrno == 0); 306 307 spdk_bs_unload(bs, bs_op_complete, NULL); 308 poll_threads(); 309 CU_ASSERT(g_bserrno == 0); 310 g_bs = NULL; 311 } 312 313 static void 314 blob_create(void) 315 { 316 struct spdk_blob_store *bs; 317 struct spdk_bs_dev *dev; 318 struct spdk_blob *blob; 319 struct spdk_blob_opts opts; 320 spdk_blob_id blobid; 321 322 dev = init_dev(); 323 324 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 325 poll_threads(); 326 CU_ASSERT(g_bserrno == 0); 327 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 328 bs = g_bs; 329 330 /* Create blob with 10 clusters */ 331 332 ut_spdk_blob_opts_init(&opts); 333 opts.num_clusters = 10; 334 335 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 336 poll_threads(); 337 CU_ASSERT(g_bserrno == 0); 338 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 339 blobid = g_blobid; 340 341 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 342 poll_threads(); 343 CU_ASSERT(g_bserrno == 0); 344 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 345 blob = g_blob; 346 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 347 348 spdk_blob_close(blob, blob_op_complete, NULL); 349 poll_threads(); 350 CU_ASSERT(g_bserrno == 0); 351 352 /* Create blob with 0 clusters */ 353 354 ut_spdk_blob_opts_init(&opts); 355 opts.num_clusters = 0; 356 357 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 358 poll_threads(); 359 CU_ASSERT(g_bserrno == 0); 360 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 361 blobid = g_blobid; 362 363 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 364 poll_threads(); 365 CU_ASSERT(g_bserrno == 0); 366 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 367 blob = g_blob; 368 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 369 370 spdk_blob_close(blob, blob_op_complete, NULL); 371 poll_threads(); 372 CU_ASSERT(g_bserrno == 0); 373 374 /* Create blob with default options (opts == NULL) */ 375 376 spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL); 377 poll_threads(); 378 CU_ASSERT(g_bserrno == 0); 379 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 380 blobid = g_blobid; 381 382 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 383 poll_threads(); 384 CU_ASSERT(g_bserrno == 0); 385 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 386 blob = g_blob; 387 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 388 389 spdk_blob_close(blob, blob_op_complete, NULL); 390 poll_threads(); 391 CU_ASSERT(g_bserrno == 0); 392 393 /* Try to create blob with size larger than blobstore */ 394 395 ut_spdk_blob_opts_init(&opts); 396 opts.num_clusters = bs->total_clusters + 1; 397 398 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 399 poll_threads(); 400 CU_ASSERT(g_bserrno == -ENOSPC); 401 402 spdk_bs_unload(bs, bs_op_complete, NULL); 403 poll_threads(); 404 CU_ASSERT(g_bserrno == 0); 405 g_bs = NULL; 406 407 } 408 409 static void 410 blob_create_internal(void) 411 { 412 struct spdk_blob_store *bs; 413 struct spdk_bs_dev *dev; 414 struct spdk_blob *blob; 415 struct spdk_blob_opts opts; 416 struct spdk_blob_xattr_opts internal_xattrs; 417 const void *value; 418 size_t value_len; 419 spdk_blob_id blobid; 420 int rc; 421 422 dev = init_dev(); 423 424 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 425 poll_threads(); 426 CU_ASSERT(g_bserrno == 0); 427 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 428 bs = g_bs; 429 430 /* Create blob with custom xattrs */ 431 432 ut_spdk_blob_opts_init(&opts); 433 _spdk_blob_xattrs_init(&internal_xattrs); 434 internal_xattrs.count = 3; 435 internal_xattrs.names = g_xattr_names; 436 internal_xattrs.get_value = _get_xattr_value; 437 internal_xattrs.ctx = &g_ctx; 438 439 _spdk_bs_create_blob(bs, &opts, &internal_xattrs, blob_op_with_id_complete, NULL); 440 poll_threads(); 441 CU_ASSERT(g_bserrno == 0); 442 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 443 blobid = g_blobid; 444 445 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 446 poll_threads(); 447 CU_ASSERT(g_bserrno == 0); 448 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 449 blob = g_blob; 450 451 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len, true); 452 CU_ASSERT(rc == 0); 453 SPDK_CU_ASSERT_FATAL(value != NULL); 454 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 455 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 456 457 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len, true); 458 CU_ASSERT(rc == 0); 459 SPDK_CU_ASSERT_FATAL(value != NULL); 460 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 461 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 462 463 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len, true); 464 CU_ASSERT(rc == 0); 465 SPDK_CU_ASSERT_FATAL(value != NULL); 466 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 467 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 468 469 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 470 CU_ASSERT(rc != 0); 471 472 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 473 CU_ASSERT(rc != 0); 474 475 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 476 CU_ASSERT(rc != 0); 477 478 spdk_blob_close(blob, blob_op_complete, NULL); 479 poll_threads(); 480 CU_ASSERT(g_bserrno == 0); 481 482 /* Create blob with NULL internal options */ 483 484 _spdk_bs_create_blob(bs, NULL, NULL, blob_op_with_id_complete, NULL); 485 poll_threads(); 486 CU_ASSERT(g_bserrno == 0); 487 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 488 blobid = g_blobid; 489 490 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 491 poll_threads(); 492 CU_ASSERT(g_bserrno == 0); 493 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 494 CU_ASSERT(TAILQ_FIRST(&g_blob->xattrs_internal) == NULL); 495 496 blob = g_blob; 497 498 spdk_blob_close(blob, blob_op_complete, NULL); 499 poll_threads(); 500 CU_ASSERT(g_bserrno == 0); 501 502 spdk_bs_unload(bs, bs_op_complete, NULL); 503 poll_threads(); 504 CU_ASSERT(g_bserrno == 0); 505 g_bs = NULL; 506 507 } 508 509 static void 510 blob_thin_provision(void) 511 { 512 struct spdk_blob_store *bs; 513 struct spdk_bs_dev *dev; 514 struct spdk_blob *blob; 515 struct spdk_blob_opts opts; 516 struct spdk_bs_opts bs_opts; 517 spdk_blob_id blobid; 518 519 dev = init_dev(); 520 spdk_bs_opts_init(&bs_opts); 521 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 522 523 /* Initialize a new blob store */ 524 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 525 poll_threads(); 526 CU_ASSERT(g_bserrno == 0); 527 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 528 529 bs = g_bs; 530 531 /* Create blob with thin provisioning enabled */ 532 533 ut_spdk_blob_opts_init(&opts); 534 opts.thin_provision = true; 535 opts.num_clusters = 10; 536 537 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 538 poll_threads(); 539 CU_ASSERT(g_bserrno == 0); 540 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 541 blobid = g_blobid; 542 543 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 544 poll_threads(); 545 CU_ASSERT(g_bserrno == 0); 546 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 547 blob = g_blob; 548 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 549 550 spdk_blob_close(blob, blob_op_complete, NULL); 551 CU_ASSERT(g_bserrno == 0); 552 553 /* Do not shut down cleanly. This makes sure that when we load again 554 * and try to recover a valid used_cluster map, that blobstore will 555 * ignore clusters with index 0 since these are unallocated clusters. 556 */ 557 _spdk_bs_free(bs); 558 559 /* Load an existing blob store and check if invalid_flags is set */ 560 dev = init_dev(); 561 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 562 spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL); 563 poll_threads(); 564 CU_ASSERT(g_bserrno == 0); 565 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 566 567 bs = g_bs; 568 569 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 570 poll_threads(); 571 CU_ASSERT(g_bserrno == 0); 572 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 573 blob = g_blob; 574 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 575 576 spdk_blob_close(blob, blob_op_complete, NULL); 577 poll_threads(); 578 CU_ASSERT(g_bserrno == 0); 579 580 spdk_bs_unload(bs, bs_op_complete, NULL); 581 poll_threads(); 582 CU_ASSERT(g_bserrno == 0); 583 g_bs = NULL; 584 } 585 586 static void 587 blob_snapshot(void) 588 { 589 struct spdk_blob_store *bs; 590 struct spdk_bs_dev *dev; 591 struct spdk_blob *blob; 592 struct spdk_blob *snapshot, *snapshot2; 593 struct spdk_blob_bs_dev *blob_bs_dev; 594 struct spdk_blob_opts opts; 595 struct spdk_blob_xattr_opts xattrs; 596 spdk_blob_id blobid; 597 spdk_blob_id snapshotid; 598 spdk_blob_id snapshotid2; 599 const void *value; 600 size_t value_len; 601 int rc; 602 spdk_blob_id ids[2]; 603 size_t count; 604 605 dev = init_dev(); 606 607 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 608 poll_threads(); 609 CU_ASSERT(g_bserrno == 0); 610 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 611 bs = g_bs; 612 613 /* Create blob with 10 clusters */ 614 ut_spdk_blob_opts_init(&opts); 615 opts.num_clusters = 10; 616 617 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 618 poll_threads(); 619 CU_ASSERT(g_bserrno == 0); 620 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 621 blobid = g_blobid; 622 623 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 624 poll_threads(); 625 CU_ASSERT(g_bserrno == 0); 626 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 627 blob = g_blob; 628 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 629 630 /* Create snapshot from blob */ 631 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 0); 632 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 633 poll_threads(); 634 CU_ASSERT(g_bserrno == 0); 635 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 636 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1); 637 snapshotid = g_blobid; 638 639 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 640 poll_threads(); 641 CU_ASSERT(g_bserrno == 0); 642 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 643 snapshot = g_blob; 644 CU_ASSERT(snapshot->data_ro == true); 645 CU_ASSERT(snapshot->md_ro == true); 646 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 647 648 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 649 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 650 CU_ASSERT(spdk_mem_all_zero(blob->active.clusters, 651 blob->active.num_clusters * sizeof(blob->active.clusters[0]))); 652 653 /* Try to create snapshot from clone with xattrs */ 654 xattrs.names = g_xattr_names; 655 xattrs.get_value = _get_xattr_value; 656 xattrs.count = 3; 657 xattrs.ctx = &g_ctx; 658 spdk_bs_create_snapshot(bs, blobid, &xattrs, blob_op_with_id_complete, NULL); 659 poll_threads(); 660 CU_ASSERT(g_bserrno == 0); 661 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 662 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2); 663 snapshotid2 = g_blobid; 664 665 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 666 CU_ASSERT(g_bserrno == 0); 667 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 668 snapshot2 = g_blob; 669 CU_ASSERT(snapshot2->data_ro == true); 670 CU_ASSERT(snapshot2->md_ro == true); 671 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 10); 672 673 /* Confirm that blob is backed by snapshot2 and snapshot2 is backed by snapshot */ 674 CU_ASSERT(snapshot->back_bs_dev == NULL); 675 SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL); 676 SPDK_CU_ASSERT_FATAL(snapshot2->back_bs_dev != NULL); 677 678 blob_bs_dev = (struct spdk_blob_bs_dev *)blob->back_bs_dev; 679 CU_ASSERT(blob_bs_dev->blob == snapshot2); 680 681 blob_bs_dev = (struct spdk_blob_bs_dev *)snapshot2->back_bs_dev; 682 CU_ASSERT(blob_bs_dev->blob == snapshot); 683 684 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[0], &value, &value_len); 685 CU_ASSERT(rc == 0); 686 SPDK_CU_ASSERT_FATAL(value != NULL); 687 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 688 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 689 690 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[1], &value, &value_len); 691 CU_ASSERT(rc == 0); 692 SPDK_CU_ASSERT_FATAL(value != NULL); 693 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 694 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 695 696 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[2], &value, &value_len); 697 CU_ASSERT(rc == 0); 698 SPDK_CU_ASSERT_FATAL(value != NULL); 699 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 700 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 701 702 /* Confirm that blob is clone of snapshot2, and snapshot2 is clone of snapshot */ 703 count = 2; 704 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid2, ids, &count) == 0); 705 CU_ASSERT(count == 1); 706 CU_ASSERT(ids[0] == blobid); 707 708 count = 2; 709 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 710 CU_ASSERT(count == 1); 711 CU_ASSERT(ids[0] == snapshotid2); 712 713 /* Try to create snapshot from snapshot */ 714 spdk_bs_create_snapshot(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 715 poll_threads(); 716 CU_ASSERT(g_bserrno == -EINVAL); 717 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 718 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2); 719 720 /* Delete blob and confirm that it is no longer on snapshot2 clone list */ 721 spdk_blob_close(blob, blob_op_complete, NULL); 722 poll_threads(); 723 CU_ASSERT(g_bserrno == 0); 724 725 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 726 poll_threads(); 727 CU_ASSERT(g_bserrno == 0); 728 count = 2; 729 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid2, ids, &count) == 0); 730 CU_ASSERT(count == 0); 731 732 /* Delete snapshot2 and confirm that it is no longer on snapshot clone list */ 733 spdk_blob_close(snapshot2, blob_op_complete, NULL); 734 poll_threads(); 735 CU_ASSERT(g_bserrno == 0); 736 737 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 738 poll_threads(); 739 CU_ASSERT(g_bserrno == 0); 740 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1); 741 count = 2; 742 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid2, ids, &count) == 0); 743 CU_ASSERT(count == 0); 744 745 spdk_blob_close(snapshot, blob_op_complete, NULL); 746 poll_threads(); 747 CU_ASSERT(g_bserrno == 0); 748 749 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 750 poll_threads(); 751 CU_ASSERT(g_bserrno == 0); 752 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 0); 753 754 spdk_bs_unload(bs, bs_op_complete, NULL); 755 poll_threads(); 756 CU_ASSERT(g_bserrno == 0); 757 g_bs = NULL; 758 } 759 760 static void 761 blob_snapshot_freeze_io(void) 762 { 763 struct spdk_io_channel *channel; 764 struct spdk_bs_channel *bs_channel; 765 struct spdk_blob_store *bs; 766 struct spdk_bs_dev *dev; 767 struct spdk_blob *blob; 768 struct spdk_blob_opts opts; 769 spdk_blob_id blobid; 770 uint32_t num_of_pages = 10; 771 uint8_t payload_read[num_of_pages * SPDK_BS_PAGE_SIZE]; 772 uint8_t payload_write[num_of_pages * SPDK_BS_PAGE_SIZE]; 773 uint8_t payload_zero[num_of_pages * SPDK_BS_PAGE_SIZE]; 774 775 memset(payload_write, 0xE5, sizeof(payload_write)); 776 memset(payload_read, 0x00, sizeof(payload_read)); 777 memset(payload_zero, 0x00, sizeof(payload_zero)); 778 779 dev = init_dev(); 780 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 781 782 /* Test freeze I/O during snapshot */ 783 784 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 785 poll_threads(); 786 CU_ASSERT(g_bserrno == 0); 787 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 788 bs = g_bs; 789 790 channel = spdk_bs_alloc_io_channel(bs); 791 bs_channel = spdk_io_channel_get_ctx(channel); 792 793 /* Create blob with 10 clusters */ 794 ut_spdk_blob_opts_init(&opts); 795 opts.num_clusters = 10; 796 opts.thin_provision = false; 797 798 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 799 poll_threads(); 800 CU_ASSERT(g_bserrno == 0); 801 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 802 blobid = g_blobid; 803 804 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 805 poll_threads(); 806 CU_ASSERT(g_bserrno == 0); 807 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 808 blob = g_blob; 809 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 810 811 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 812 813 /* This is implementation specific. 814 * Flag 'frozen_io' is set in _spdk_bs_snapshot_freeze_cpl callback. 815 * Four async I/O operations happen before that. */ 816 poll_thread_times(0, 3); 817 818 CU_ASSERT(TAILQ_EMPTY(&bs_channel->queued_io)); 819 820 /* Blob I/O should be frozen here */ 821 CU_ASSERT(blob->frozen_refcnt == 1); 822 823 /* Write to the blob */ 824 spdk_blob_io_write(blob, channel, payload_write, 0, num_of_pages, blob_op_complete, NULL); 825 826 /* Verify that I/O is queued */ 827 CU_ASSERT(!TAILQ_EMPTY(&bs_channel->queued_io)); 828 /* Verify that payload is not written to disk */ 829 CU_ASSERT(memcmp(payload_zero, &g_dev_buffer[blob->active.clusters[0]*SPDK_BS_PAGE_SIZE], 830 SPDK_BS_PAGE_SIZE) == 0); 831 832 /* Finish all operations including spdk_bs_create_snapshot */ 833 poll_threads(); 834 835 /* Verify snapshot */ 836 CU_ASSERT(g_bserrno == 0); 837 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 838 839 /* Verify that blob has unset frozen_io */ 840 CU_ASSERT(blob->frozen_refcnt == 0); 841 842 /* Verify that postponed I/O completed successfully by comparing payload */ 843 spdk_blob_io_read(blob, channel, payload_read, 0, num_of_pages, blob_op_complete, NULL); 844 poll_threads(); 845 CU_ASSERT(g_bserrno == 0); 846 CU_ASSERT(memcmp(payload_write, payload_read, num_of_pages * SPDK_BS_PAGE_SIZE) == 0); 847 848 spdk_blob_close(blob, blob_op_complete, NULL); 849 poll_threads(); 850 CU_ASSERT(g_bserrno == 0); 851 852 spdk_bs_free_io_channel(channel); 853 poll_threads(); 854 855 spdk_bs_unload(bs, bs_op_complete, NULL); 856 poll_threads(); 857 CU_ASSERT(g_bserrno == 0); 858 g_bs = NULL; 859 } 860 861 static void 862 blob_clone(void) 863 { 864 struct spdk_blob_store *bs; 865 struct spdk_bs_dev *dev; 866 struct spdk_blob_opts opts; 867 struct spdk_blob *blob, *snapshot, *clone; 868 spdk_blob_id blobid, cloneid, snapshotid; 869 struct spdk_blob_xattr_opts xattrs; 870 const void *value; 871 size_t value_len; 872 int rc; 873 874 dev = init_dev(); 875 876 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 877 poll_threads(); 878 CU_ASSERT(g_bserrno == 0); 879 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 880 bs = g_bs; 881 882 /* Create blob with 10 clusters */ 883 884 ut_spdk_blob_opts_init(&opts); 885 opts.num_clusters = 10; 886 887 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 888 poll_threads(); 889 CU_ASSERT(g_bserrno == 0); 890 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 891 blobid = g_blobid; 892 893 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 894 poll_threads(); 895 CU_ASSERT(g_bserrno == 0); 896 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 897 blob = g_blob; 898 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 899 900 /* Create snapshot */ 901 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 902 poll_threads(); 903 CU_ASSERT(g_bserrno == 0); 904 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 905 snapshotid = g_blobid; 906 907 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 908 poll_threads(); 909 CU_ASSERT(g_bserrno == 0); 910 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 911 snapshot = g_blob; 912 CU_ASSERT(snapshot->data_ro == true); 913 CU_ASSERT(snapshot->md_ro == true); 914 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 915 916 spdk_blob_close(snapshot, blob_op_complete, NULL); 917 poll_threads(); 918 CU_ASSERT(g_bserrno == 0); 919 920 /* Create clone from snapshot with xattrs */ 921 xattrs.names = g_xattr_names; 922 xattrs.get_value = _get_xattr_value; 923 xattrs.count = 3; 924 xattrs.ctx = &g_ctx; 925 926 spdk_bs_create_clone(bs, snapshotid, &xattrs, blob_op_with_id_complete, NULL); 927 poll_threads(); 928 CU_ASSERT(g_bserrno == 0); 929 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 930 cloneid = g_blobid; 931 932 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 933 poll_threads(); 934 CU_ASSERT(g_bserrno == 0); 935 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 936 clone = g_blob; 937 CU_ASSERT(clone->data_ro == false); 938 CU_ASSERT(clone->md_ro == false); 939 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 940 941 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[0], &value, &value_len); 942 CU_ASSERT(rc == 0); 943 SPDK_CU_ASSERT_FATAL(value != NULL); 944 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 945 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 946 947 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[1], &value, &value_len); 948 CU_ASSERT(rc == 0); 949 SPDK_CU_ASSERT_FATAL(value != NULL); 950 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 951 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 952 953 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[2], &value, &value_len); 954 CU_ASSERT(rc == 0); 955 SPDK_CU_ASSERT_FATAL(value != NULL); 956 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 957 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 958 959 960 spdk_blob_close(clone, blob_op_complete, NULL); 961 poll_threads(); 962 CU_ASSERT(g_bserrno == 0); 963 964 /* Try to create clone from not read only blob */ 965 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 966 poll_threads(); 967 CU_ASSERT(g_bserrno == -EINVAL); 968 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 969 970 /* Mark blob as read only */ 971 spdk_blob_set_read_only(blob); 972 spdk_blob_sync_md(blob, blob_op_complete, NULL); 973 poll_threads(); 974 CU_ASSERT(g_bserrno == 0); 975 976 /* Create clone from read only blob */ 977 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 978 poll_threads(); 979 CU_ASSERT(g_bserrno == 0); 980 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 981 cloneid = g_blobid; 982 983 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 984 poll_threads(); 985 CU_ASSERT(g_bserrno == 0); 986 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 987 clone = g_blob; 988 CU_ASSERT(clone->data_ro == false); 989 CU_ASSERT(clone->md_ro == false); 990 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 991 992 spdk_blob_close(clone, blob_op_complete, NULL); 993 poll_threads(); 994 CU_ASSERT(g_bserrno == 0); 995 996 spdk_blob_close(blob, blob_op_complete, NULL); 997 poll_threads(); 998 CU_ASSERT(g_bserrno == 0); 999 1000 spdk_bs_unload(bs, bs_op_complete, NULL); 1001 poll_threads(); 1002 CU_ASSERT(g_bserrno == 0); 1003 g_bs = NULL; 1004 1005 } 1006 1007 static void 1008 _blob_inflate(bool decouple_parent) 1009 { 1010 struct spdk_blob_store *bs; 1011 struct spdk_bs_dev *dev; 1012 struct spdk_blob_opts opts; 1013 struct spdk_blob *blob, *snapshot; 1014 spdk_blob_id blobid, snapshotid; 1015 struct spdk_io_channel *channel; 1016 uint64_t free_clusters; 1017 1018 dev = init_dev(); 1019 1020 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1021 poll_threads(); 1022 CU_ASSERT(g_bserrno == 0); 1023 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1024 bs = g_bs; 1025 1026 channel = spdk_bs_alloc_io_channel(bs); 1027 SPDK_CU_ASSERT_FATAL(channel != NULL); 1028 1029 /* Create blob with 10 clusters */ 1030 1031 ut_spdk_blob_opts_init(&opts); 1032 opts.num_clusters = 10; 1033 opts.thin_provision = true; 1034 1035 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1036 poll_threads(); 1037 CU_ASSERT(g_bserrno == 0); 1038 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1039 blobid = g_blobid; 1040 1041 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1042 poll_threads(); 1043 CU_ASSERT(g_bserrno == 0); 1044 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1045 blob = g_blob; 1046 1047 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1048 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true); 1049 1050 /* 1) Blob with no parent */ 1051 if (decouple_parent) { 1052 /* Decouple parent of blob with no parent (should fail) */ 1053 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 1054 poll_threads(); 1055 CU_ASSERT(g_bserrno != 0); 1056 } else { 1057 /* Inflate of thin blob with no parent should made it thick */ 1058 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 1059 poll_threads(); 1060 CU_ASSERT(g_bserrno == 0); 1061 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false); 1062 } 1063 1064 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 1065 poll_threads(); 1066 CU_ASSERT(g_bserrno == 0); 1067 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1068 snapshotid = g_blobid; 1069 1070 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true); 1071 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1072 1073 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 1074 poll_threads(); 1075 CU_ASSERT(g_bserrno == 0); 1076 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1077 snapshot = g_blob; 1078 CU_ASSERT(snapshot->data_ro == true); 1079 CU_ASSERT(snapshot->md_ro == true); 1080 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 1081 1082 spdk_blob_close(snapshot, blob_op_complete, NULL); 1083 poll_threads(); 1084 CU_ASSERT(g_bserrno == 0); 1085 1086 free_clusters = spdk_bs_free_cluster_count(bs); 1087 1088 /* 2) Blob with parent */ 1089 if (!decouple_parent) { 1090 /* Do full blob inflation */ 1091 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 1092 poll_threads(); 1093 CU_ASSERT(g_bserrno == 0); 1094 /* all 10 clusters should be allocated */ 1095 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 10); 1096 } else { 1097 /* Decouple parent of blob */ 1098 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 1099 poll_threads(); 1100 CU_ASSERT(g_bserrno == 0); 1101 /* when only parent is removed, none of the clusters should be allocated */ 1102 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters); 1103 } 1104 1105 /* Now, it should be possible to delete snapshot */ 1106 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 1107 poll_threads(); 1108 CU_ASSERT(g_bserrno == 0); 1109 1110 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1111 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == decouple_parent); 1112 1113 spdk_blob_close(blob, blob_op_complete, NULL); 1114 poll_threads(); 1115 CU_ASSERT(g_bserrno == 0); 1116 1117 spdk_bs_unload(bs, bs_op_complete, NULL); 1118 poll_threads(); 1119 CU_ASSERT(g_bserrno == 0); 1120 g_bs = NULL; 1121 1122 spdk_bs_free_io_channel(channel); 1123 poll_threads(); 1124 } 1125 1126 static void 1127 blob_inflate(void) 1128 { 1129 _blob_inflate(false); 1130 _blob_inflate(true); 1131 } 1132 1133 static void 1134 blob_delete(void) 1135 { 1136 struct spdk_blob_store *bs; 1137 struct spdk_bs_dev *dev; 1138 struct spdk_blob_opts blob_opts; 1139 spdk_blob_id blobid; 1140 1141 dev = init_dev(); 1142 1143 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1144 poll_threads(); 1145 CU_ASSERT(g_bserrno == 0); 1146 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1147 bs = g_bs; 1148 1149 /* Create a blob and then delete it. */ 1150 ut_spdk_blob_opts_init(&blob_opts); 1151 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 1152 poll_threads(); 1153 CU_ASSERT(g_bserrno == 0); 1154 CU_ASSERT(g_blobid > 0); 1155 blobid = g_blobid; 1156 1157 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 1158 poll_threads(); 1159 CU_ASSERT(g_bserrno == 0); 1160 1161 /* Try to open the blob */ 1162 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1163 poll_threads(); 1164 CU_ASSERT(g_bserrno == -ENOENT); 1165 1166 spdk_bs_unload(bs, bs_op_complete, NULL); 1167 poll_threads(); 1168 CU_ASSERT(g_bserrno == 0); 1169 g_bs = NULL; 1170 } 1171 1172 static void 1173 blob_resize(void) 1174 { 1175 struct spdk_blob_store *bs; 1176 struct spdk_bs_dev *dev; 1177 struct spdk_blob *blob; 1178 struct spdk_blob_opts blob_opts; 1179 spdk_blob_id blobid; 1180 uint64_t free_clusters; 1181 1182 dev = init_dev(); 1183 1184 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1185 poll_threads(); 1186 CU_ASSERT(g_bserrno == 0); 1187 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1188 bs = g_bs; 1189 free_clusters = spdk_bs_free_cluster_count(bs); 1190 1191 ut_spdk_blob_opts_init(&blob_opts); 1192 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 1193 poll_threads(); 1194 CU_ASSERT(g_bserrno == 0); 1195 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1196 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 1197 blobid = g_blobid; 1198 1199 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1200 poll_threads(); 1201 CU_ASSERT(g_bserrno == 0); 1202 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1203 blob = g_blob; 1204 1205 /* Confirm that resize fails if blob is marked read-only. */ 1206 blob->md_ro = true; 1207 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1208 poll_threads(); 1209 CU_ASSERT(g_bserrno == -EPERM); 1210 blob->md_ro = false; 1211 1212 /* The blob started at 0 clusters. Resize it to be 5. */ 1213 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1214 poll_threads(); 1215 CU_ASSERT(g_bserrno == 0); 1216 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 1217 1218 /* Shrink the blob to 3 clusters. This will not actually release 1219 * the old clusters until the blob is synced. 1220 */ 1221 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 1222 poll_threads(); 1223 CU_ASSERT(g_bserrno == 0); 1224 /* Verify there are still 5 clusters in use */ 1225 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 1226 1227 spdk_blob_sync_md(blob, blob_op_complete, NULL); 1228 poll_threads(); 1229 CU_ASSERT(g_bserrno == 0); 1230 /* Now there are only 3 clusters in use */ 1231 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 1232 1233 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 1234 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 1235 poll_threads(); 1236 CU_ASSERT(g_bserrno == 0); 1237 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 1238 1239 /* Try to resize the blob to size larger than blobstore. */ 1240 spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL); 1241 poll_threads(); 1242 CU_ASSERT(g_bserrno == -ENOSPC); 1243 1244 spdk_blob_close(blob, blob_op_complete, NULL); 1245 poll_threads(); 1246 CU_ASSERT(g_bserrno == 0); 1247 1248 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 1249 poll_threads(); 1250 CU_ASSERT(g_bserrno == 0); 1251 1252 spdk_bs_unload(bs, bs_op_complete, NULL); 1253 poll_threads(); 1254 CU_ASSERT(g_bserrno == 0); 1255 g_bs = NULL; 1256 } 1257 1258 static void 1259 blob_read_only(void) 1260 { 1261 struct spdk_blob_store *bs; 1262 struct spdk_bs_dev *dev; 1263 struct spdk_blob *blob; 1264 struct spdk_bs_opts opts; 1265 struct spdk_blob_opts blob_opts; 1266 spdk_blob_id blobid; 1267 int rc; 1268 1269 dev = init_dev(); 1270 spdk_bs_opts_init(&opts); 1271 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1272 1273 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1274 poll_threads(); 1275 CU_ASSERT(g_bserrno == 0); 1276 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1277 bs = g_bs; 1278 1279 ut_spdk_blob_opts_init(&blob_opts); 1280 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 1281 poll_threads(); 1282 CU_ASSERT(g_bserrno == 0); 1283 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1284 blobid = g_blobid; 1285 1286 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1287 poll_threads(); 1288 CU_ASSERT(g_bserrno == 0); 1289 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1290 blob = g_blob; 1291 1292 rc = spdk_blob_set_read_only(blob); 1293 CU_ASSERT(rc == 0); 1294 1295 CU_ASSERT(blob->data_ro == false); 1296 CU_ASSERT(blob->md_ro == false); 1297 1298 spdk_blob_sync_md(blob, bs_op_complete, NULL); 1299 poll_threads(); 1300 1301 CU_ASSERT(blob->data_ro == true); 1302 CU_ASSERT(blob->md_ro == true); 1303 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1304 1305 spdk_blob_close(blob, blob_op_complete, NULL); 1306 poll_threads(); 1307 CU_ASSERT(g_bserrno == 0); 1308 1309 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1310 poll_threads(); 1311 CU_ASSERT(g_bserrno == 0); 1312 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1313 blob = g_blob; 1314 1315 CU_ASSERT(blob->data_ro == true); 1316 CU_ASSERT(blob->md_ro == true); 1317 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1318 1319 spdk_blob_close(blob, blob_op_complete, NULL); 1320 poll_threads(); 1321 CU_ASSERT(g_bserrno == 0); 1322 1323 spdk_bs_unload(bs, bs_op_complete, NULL); 1324 poll_threads(); 1325 CU_ASSERT(g_bserrno == 0); 1326 g_bs = NULL; 1327 g_blob = NULL; 1328 g_blobid = 0; 1329 1330 /* Load an existing blob store */ 1331 dev = init_dev(); 1332 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1333 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1334 poll_threads(); 1335 CU_ASSERT(g_bserrno == 0); 1336 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1337 bs = g_bs; 1338 1339 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1340 poll_threads(); 1341 CU_ASSERT(g_bserrno == 0); 1342 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1343 blob = g_blob; 1344 1345 CU_ASSERT(blob->data_ro == true); 1346 CU_ASSERT(blob->md_ro == true); 1347 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1348 1349 spdk_blob_close(blob, blob_op_complete, NULL); 1350 poll_threads(); 1351 CU_ASSERT(g_bserrno == 0); 1352 1353 spdk_bs_unload(bs, bs_op_complete, NULL); 1354 poll_threads(); 1355 CU_ASSERT(g_bserrno == 0); 1356 1357 } 1358 1359 static void 1360 channel_ops(void) 1361 { 1362 struct spdk_blob_store *bs; 1363 struct spdk_bs_dev *dev; 1364 struct spdk_io_channel *channel; 1365 1366 dev = init_dev(); 1367 1368 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1369 poll_threads(); 1370 CU_ASSERT(g_bserrno == 0); 1371 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1372 bs = g_bs; 1373 1374 channel = spdk_bs_alloc_io_channel(bs); 1375 CU_ASSERT(channel != NULL); 1376 1377 spdk_bs_free_io_channel(channel); 1378 poll_threads(); 1379 1380 spdk_bs_unload(bs, bs_op_complete, NULL); 1381 poll_threads(); 1382 CU_ASSERT(g_bserrno == 0); 1383 g_bs = NULL; 1384 } 1385 1386 static void 1387 blob_write(void) 1388 { 1389 struct spdk_blob_store *bs; 1390 struct spdk_bs_dev *dev; 1391 struct spdk_blob *blob; 1392 struct spdk_blob_opts blob_opts; 1393 struct spdk_io_channel *channel; 1394 spdk_blob_id blobid; 1395 uint64_t pages_per_cluster; 1396 uint8_t payload[10 * 4096]; 1397 1398 dev = init_dev(); 1399 1400 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1401 poll_threads(); 1402 CU_ASSERT(g_bserrno == 0); 1403 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1404 bs = g_bs; 1405 1406 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1407 1408 channel = spdk_bs_alloc_io_channel(bs); 1409 CU_ASSERT(channel != NULL); 1410 1411 ut_spdk_blob_opts_init(&blob_opts); 1412 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 1413 poll_threads(); 1414 CU_ASSERT(g_bserrno == 0); 1415 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1416 blobid = g_blobid; 1417 1418 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1419 poll_threads(); 1420 CU_ASSERT(g_bserrno == 0); 1421 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1422 blob = g_blob; 1423 1424 /* Write to a blob with 0 size */ 1425 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1426 poll_threads(); 1427 CU_ASSERT(g_bserrno == -EINVAL); 1428 1429 /* Resize the blob */ 1430 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1431 poll_threads(); 1432 CU_ASSERT(g_bserrno == 0); 1433 1434 /* Confirm that write fails if blob is marked read-only. */ 1435 blob->data_ro = true; 1436 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1437 poll_threads(); 1438 CU_ASSERT(g_bserrno == -EPERM); 1439 blob->data_ro = false; 1440 1441 /* Write to the blob */ 1442 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1443 poll_threads(); 1444 CU_ASSERT(g_bserrno == 0); 1445 1446 /* Write starting beyond the end */ 1447 spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1448 NULL); 1449 poll_threads(); 1450 CU_ASSERT(g_bserrno == -EINVAL); 1451 1452 /* Write starting at a valid location but going off the end */ 1453 spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1454 blob_op_complete, NULL); 1455 poll_threads(); 1456 CU_ASSERT(g_bserrno == -EINVAL); 1457 1458 spdk_blob_close(blob, blob_op_complete, NULL); 1459 poll_threads(); 1460 CU_ASSERT(g_bserrno == 0); 1461 1462 spdk_bs_free_io_channel(channel); 1463 poll_threads(); 1464 1465 spdk_bs_unload(bs, bs_op_complete, NULL); 1466 poll_threads(); 1467 CU_ASSERT(g_bserrno == 0); 1468 g_bs = NULL; 1469 } 1470 1471 static void 1472 blob_read(void) 1473 { 1474 struct spdk_blob_store *bs; 1475 struct spdk_bs_dev *dev; 1476 struct spdk_blob *blob; 1477 struct spdk_blob_opts blob_opts; 1478 struct spdk_io_channel *channel; 1479 spdk_blob_id blobid; 1480 uint64_t pages_per_cluster; 1481 uint8_t payload[10 * 4096]; 1482 1483 dev = init_dev(); 1484 1485 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1486 poll_threads(); 1487 CU_ASSERT(g_bserrno == 0); 1488 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1489 bs = g_bs; 1490 1491 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1492 1493 channel = spdk_bs_alloc_io_channel(bs); 1494 CU_ASSERT(channel != NULL); 1495 1496 ut_spdk_blob_opts_init(&blob_opts); 1497 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 1498 poll_threads(); 1499 CU_ASSERT(g_bserrno == 0); 1500 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1501 blobid = g_blobid; 1502 1503 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1504 poll_threads(); 1505 CU_ASSERT(g_bserrno == 0); 1506 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1507 blob = g_blob; 1508 1509 /* Read from a blob with 0 size */ 1510 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1511 poll_threads(); 1512 CU_ASSERT(g_bserrno == -EINVAL); 1513 1514 /* Resize the blob */ 1515 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1516 poll_threads(); 1517 CU_ASSERT(g_bserrno == 0); 1518 1519 /* Confirm that read passes if blob is marked read-only. */ 1520 blob->data_ro = true; 1521 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1522 poll_threads(); 1523 CU_ASSERT(g_bserrno == 0); 1524 blob->data_ro = false; 1525 1526 /* Read from the blob */ 1527 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1528 poll_threads(); 1529 CU_ASSERT(g_bserrno == 0); 1530 1531 /* Read starting beyond the end */ 1532 spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1533 NULL); 1534 poll_threads(); 1535 CU_ASSERT(g_bserrno == -EINVAL); 1536 1537 /* Read starting at a valid location but going off the end */ 1538 spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1539 blob_op_complete, NULL); 1540 poll_threads(); 1541 CU_ASSERT(g_bserrno == -EINVAL); 1542 1543 spdk_blob_close(blob, blob_op_complete, NULL); 1544 poll_threads(); 1545 CU_ASSERT(g_bserrno == 0); 1546 1547 spdk_bs_free_io_channel(channel); 1548 poll_threads(); 1549 1550 spdk_bs_unload(bs, bs_op_complete, NULL); 1551 poll_threads(); 1552 CU_ASSERT(g_bserrno == 0); 1553 g_bs = NULL; 1554 } 1555 1556 static void 1557 blob_rw_verify(void) 1558 { 1559 struct spdk_blob_store *bs; 1560 struct spdk_bs_dev *dev; 1561 struct spdk_blob *blob; 1562 struct spdk_blob_opts blob_opts; 1563 struct spdk_io_channel *channel; 1564 spdk_blob_id blobid; 1565 uint8_t payload_read[10 * 4096]; 1566 uint8_t payload_write[10 * 4096]; 1567 1568 dev = init_dev(); 1569 1570 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1571 poll_threads(); 1572 CU_ASSERT(g_bserrno == 0); 1573 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1574 bs = g_bs; 1575 1576 channel = spdk_bs_alloc_io_channel(bs); 1577 CU_ASSERT(channel != NULL); 1578 1579 ut_spdk_blob_opts_init(&blob_opts); 1580 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 1581 poll_threads(); 1582 CU_ASSERT(g_bserrno == 0); 1583 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1584 blobid = g_blobid; 1585 1586 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1587 poll_threads(); 1588 CU_ASSERT(g_bserrno == 0); 1589 CU_ASSERT(g_blob != NULL); 1590 blob = g_blob; 1591 1592 spdk_blob_resize(blob, 32, blob_op_complete, NULL); 1593 poll_threads(); 1594 CU_ASSERT(g_bserrno == 0); 1595 1596 memset(payload_write, 0xE5, sizeof(payload_write)); 1597 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 1598 poll_threads(); 1599 CU_ASSERT(g_bserrno == 0); 1600 1601 memset(payload_read, 0x00, sizeof(payload_read)); 1602 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 1603 poll_threads(); 1604 CU_ASSERT(g_bserrno == 0); 1605 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 1606 1607 spdk_blob_close(blob, blob_op_complete, NULL); 1608 poll_threads(); 1609 CU_ASSERT(g_bserrno == 0); 1610 1611 spdk_bs_free_io_channel(channel); 1612 poll_threads(); 1613 1614 spdk_bs_unload(bs, bs_op_complete, NULL); 1615 poll_threads(); 1616 CU_ASSERT(g_bserrno == 0); 1617 g_bs = NULL; 1618 } 1619 1620 static void 1621 blob_rw_verify_iov(void) 1622 { 1623 struct spdk_blob_store *bs; 1624 struct spdk_bs_dev *dev; 1625 struct spdk_blob *blob; 1626 struct spdk_blob_opts blob_opts; 1627 struct spdk_io_channel *channel; 1628 spdk_blob_id blobid; 1629 uint8_t payload_read[10 * 4096]; 1630 uint8_t payload_write[10 * 4096]; 1631 struct iovec iov_read[3]; 1632 struct iovec iov_write[3]; 1633 void *buf; 1634 1635 dev = init_dev(); 1636 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1637 1638 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1639 poll_threads(); 1640 CU_ASSERT(g_bserrno == 0); 1641 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1642 bs = g_bs; 1643 1644 channel = spdk_bs_alloc_io_channel(bs); 1645 CU_ASSERT(channel != NULL); 1646 1647 ut_spdk_blob_opts_init(&blob_opts); 1648 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 1649 poll_threads(); 1650 CU_ASSERT(g_bserrno == 0); 1651 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1652 blobid = g_blobid; 1653 1654 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1655 poll_threads(); 1656 CU_ASSERT(g_bserrno == 0); 1657 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1658 blob = g_blob; 1659 1660 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1661 poll_threads(); 1662 CU_ASSERT(g_bserrno == 0); 1663 1664 /* 1665 * Manually adjust the offset of the blob's second cluster. This allows 1666 * us to make sure that the readv/write code correctly accounts for I/O 1667 * that cross cluster boundaries. Start by asserting that the allocated 1668 * clusters are where we expect before modifying the second cluster. 1669 */ 1670 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 1671 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 1672 blob->active.clusters[1] = 3 * 256; 1673 1674 memset(payload_write, 0xE5, sizeof(payload_write)); 1675 iov_write[0].iov_base = payload_write; 1676 iov_write[0].iov_len = 1 * 4096; 1677 iov_write[1].iov_base = payload_write + 1 * 4096; 1678 iov_write[1].iov_len = 5 * 4096; 1679 iov_write[2].iov_base = payload_write + 6 * 4096; 1680 iov_write[2].iov_len = 4 * 4096; 1681 /* 1682 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1683 * will get written to the first cluster, the last 4 to the second cluster. 1684 */ 1685 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1686 poll_threads(); 1687 CU_ASSERT(g_bserrno == 0); 1688 1689 memset(payload_read, 0xAA, sizeof(payload_read)); 1690 iov_read[0].iov_base = payload_read; 1691 iov_read[0].iov_len = 3 * 4096; 1692 iov_read[1].iov_base = payload_read + 3 * 4096; 1693 iov_read[1].iov_len = 4 * 4096; 1694 iov_read[2].iov_base = payload_read + 7 * 4096; 1695 iov_read[2].iov_len = 3 * 4096; 1696 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 1697 poll_threads(); 1698 CU_ASSERT(g_bserrno == 0); 1699 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 1700 1701 buf = calloc(1, 256 * 4096); 1702 SPDK_CU_ASSERT_FATAL(buf != NULL); 1703 /* Check that cluster 2 on "disk" was not modified. */ 1704 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 1705 free(buf); 1706 1707 spdk_blob_close(blob, blob_op_complete, NULL); 1708 poll_threads(); 1709 CU_ASSERT(g_bserrno == 0); 1710 1711 spdk_bs_free_io_channel(channel); 1712 poll_threads(); 1713 1714 spdk_bs_unload(bs, bs_op_complete, NULL); 1715 poll_threads(); 1716 CU_ASSERT(g_bserrno == 0); 1717 g_bs = NULL; 1718 } 1719 1720 static uint32_t 1721 bs_channel_get_req_count(struct spdk_io_channel *_channel) 1722 { 1723 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 1724 struct spdk_bs_request_set *set; 1725 uint32_t count = 0; 1726 1727 TAILQ_FOREACH(set, &channel->reqs, link) { 1728 count++; 1729 } 1730 1731 return count; 1732 } 1733 1734 static void 1735 blob_rw_verify_iov_nomem(void) 1736 { 1737 struct spdk_blob_store *bs; 1738 struct spdk_bs_dev *dev; 1739 struct spdk_blob *blob; 1740 struct spdk_blob_opts blob_opts; 1741 struct spdk_io_channel *channel; 1742 spdk_blob_id blobid; 1743 uint8_t payload_write[10 * 4096]; 1744 struct iovec iov_write[3]; 1745 uint32_t req_count; 1746 1747 dev = init_dev(); 1748 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1749 1750 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1751 poll_threads(); 1752 CU_ASSERT(g_bserrno == 0); 1753 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1754 bs = g_bs; 1755 1756 channel = spdk_bs_alloc_io_channel(bs); 1757 CU_ASSERT(channel != NULL); 1758 1759 ut_spdk_blob_opts_init(&blob_opts); 1760 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 1761 poll_threads(); 1762 CU_ASSERT(g_bserrno == 0); 1763 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1764 blobid = g_blobid; 1765 1766 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1767 poll_threads(); 1768 CU_ASSERT(g_bserrno == 0); 1769 CU_ASSERT(g_blob != NULL); 1770 blob = g_blob; 1771 1772 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1773 poll_threads(); 1774 CU_ASSERT(g_bserrno == 0); 1775 1776 /* 1777 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1778 * will get written to the first cluster, the last 4 to the second cluster. 1779 */ 1780 iov_write[0].iov_base = payload_write; 1781 iov_write[0].iov_len = 1 * 4096; 1782 iov_write[1].iov_base = payload_write + 1 * 4096; 1783 iov_write[1].iov_len = 5 * 4096; 1784 iov_write[2].iov_base = payload_write + 6 * 4096; 1785 iov_write[2].iov_len = 4 * 4096; 1786 MOCK_SET(calloc, NULL); 1787 req_count = bs_channel_get_req_count(channel); 1788 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1789 poll_threads(); 1790 CU_ASSERT(g_bserrno = -ENOMEM); 1791 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 1792 MOCK_CLEAR(calloc); 1793 1794 spdk_blob_close(blob, blob_op_complete, NULL); 1795 poll_threads(); 1796 CU_ASSERT(g_bserrno == 0); 1797 1798 spdk_bs_free_io_channel(channel); 1799 poll_threads(); 1800 1801 spdk_bs_unload(bs, bs_op_complete, NULL); 1802 poll_threads(); 1803 CU_ASSERT(g_bserrno == 0); 1804 g_bs = NULL; 1805 } 1806 1807 static void 1808 blob_rw_iov_read_only(void) 1809 { 1810 struct spdk_blob_store *bs; 1811 struct spdk_bs_dev *dev; 1812 struct spdk_blob *blob; 1813 struct spdk_io_channel *channel; 1814 spdk_blob_id blobid; 1815 uint8_t payload_read[4096]; 1816 uint8_t payload_write[4096]; 1817 struct iovec iov_read; 1818 struct iovec iov_write; 1819 struct spdk_blob_opts blob_opts; 1820 1821 dev = init_dev(); 1822 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1823 1824 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1825 poll_threads(); 1826 CU_ASSERT(g_bserrno == 0); 1827 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1828 bs = g_bs; 1829 1830 channel = spdk_bs_alloc_io_channel(bs); 1831 CU_ASSERT(channel != NULL); 1832 1833 ut_spdk_blob_opts_init(&blob_opts); 1834 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 1835 poll_threads(); 1836 CU_ASSERT(g_bserrno == 0); 1837 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1838 blobid = g_blobid; 1839 1840 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1841 poll_threads(); 1842 CU_ASSERT(g_bserrno == 0); 1843 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1844 blob = g_blob; 1845 1846 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1847 poll_threads(); 1848 CU_ASSERT(g_bserrno == 0); 1849 1850 /* Verify that writev failed if read_only flag is set. */ 1851 blob->data_ro = true; 1852 iov_write.iov_base = payload_write; 1853 iov_write.iov_len = sizeof(payload_write); 1854 spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL); 1855 poll_threads(); 1856 CU_ASSERT(g_bserrno == -EPERM); 1857 1858 /* Verify that reads pass if data_ro flag is set. */ 1859 iov_read.iov_base = payload_read; 1860 iov_read.iov_len = sizeof(payload_read); 1861 spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL); 1862 poll_threads(); 1863 CU_ASSERT(g_bserrno == 0); 1864 1865 spdk_blob_close(blob, blob_op_complete, NULL); 1866 poll_threads(); 1867 CU_ASSERT(g_bserrno == 0); 1868 1869 spdk_bs_free_io_channel(channel); 1870 poll_threads(); 1871 1872 spdk_bs_unload(bs, bs_op_complete, NULL); 1873 poll_threads(); 1874 CU_ASSERT(g_bserrno == 0); 1875 g_bs = NULL; 1876 } 1877 1878 static void 1879 _blob_io_read_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel, 1880 uint8_t *payload, uint64_t offset, uint64_t length, 1881 spdk_blob_op_complete cb_fn, void *cb_arg) 1882 { 1883 uint64_t i; 1884 uint8_t *buf; 1885 uint64_t page_size = spdk_bs_get_page_size(blob->bs); 1886 1887 /* To be sure that operation is NOT splitted, read one page at the time */ 1888 buf = payload; 1889 for (i = 0; i < length; i++) { 1890 spdk_blob_io_read(blob, channel, buf, i + offset, 1, blob_op_complete, NULL); 1891 poll_threads(); 1892 if (g_bserrno != 0) { 1893 /* Pass the error code up */ 1894 break; 1895 } 1896 buf += page_size; 1897 } 1898 1899 cb_fn(cb_arg, g_bserrno); 1900 } 1901 1902 static void 1903 _blob_io_write_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel, 1904 uint8_t *payload, uint64_t offset, uint64_t length, 1905 spdk_blob_op_complete cb_fn, void *cb_arg) 1906 { 1907 uint64_t i; 1908 uint8_t *buf; 1909 uint64_t page_size = spdk_bs_get_page_size(blob->bs); 1910 1911 /* To be sure that operation is NOT splitted, write one page at the time */ 1912 buf = payload; 1913 for (i = 0; i < length; i++) { 1914 spdk_blob_io_write(blob, channel, buf, i + offset, 1, blob_op_complete, NULL); 1915 poll_threads(); 1916 if (g_bserrno != 0) { 1917 /* Pass the error code up */ 1918 break; 1919 } 1920 buf += page_size; 1921 } 1922 1923 cb_fn(cb_arg, g_bserrno); 1924 } 1925 1926 static void 1927 blob_operation_split_rw(void) 1928 { 1929 struct spdk_blob_store *bs; 1930 struct spdk_bs_dev *dev; 1931 struct spdk_blob *blob; 1932 struct spdk_io_channel *channel; 1933 struct spdk_blob_opts opts; 1934 spdk_blob_id blobid; 1935 uint64_t cluster_size; 1936 1937 uint64_t payload_size; 1938 uint8_t *payload_read; 1939 uint8_t *payload_write; 1940 uint8_t *payload_pattern; 1941 1942 uint64_t page_size; 1943 uint64_t pages_per_cluster; 1944 uint64_t pages_per_payload; 1945 1946 uint64_t i; 1947 1948 dev = init_dev(); 1949 1950 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1951 poll_threads(); 1952 CU_ASSERT(g_bserrno == 0); 1953 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1954 bs = g_bs; 1955 1956 cluster_size = spdk_bs_get_cluster_size(bs); 1957 page_size = spdk_bs_get_page_size(bs); 1958 pages_per_cluster = cluster_size / page_size; 1959 pages_per_payload = pages_per_cluster * 5; 1960 payload_size = cluster_size * 5; 1961 1962 payload_read = malloc(payload_size); 1963 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 1964 1965 payload_write = malloc(payload_size); 1966 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 1967 1968 payload_pattern = malloc(payload_size); 1969 SPDK_CU_ASSERT_FATAL(payload_pattern != NULL); 1970 1971 /* Prepare random pattern to write */ 1972 memset(payload_pattern, 0xFF, payload_size); 1973 for (i = 0; i < pages_per_payload; i++) { 1974 *((uint64_t *)(payload_pattern + page_size * i)) = (i + 1); 1975 } 1976 1977 channel = spdk_bs_alloc_io_channel(bs); 1978 SPDK_CU_ASSERT_FATAL(channel != NULL); 1979 1980 /* Create blob */ 1981 ut_spdk_blob_opts_init(&opts); 1982 opts.thin_provision = false; 1983 opts.num_clusters = 5; 1984 1985 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1986 poll_threads(); 1987 CU_ASSERT(g_bserrno == 0); 1988 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1989 blobid = g_blobid; 1990 1991 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1992 poll_threads(); 1993 CU_ASSERT(g_bserrno == 0); 1994 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1995 blob = g_blob; 1996 1997 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 1998 1999 /* Initial read should return zeroed payload */ 2000 memset(payload_read, 0xFF, payload_size); 2001 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 2002 poll_threads(); 2003 CU_ASSERT(g_bserrno == 0); 2004 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 2005 2006 /* Fill whole blob except last page */ 2007 spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload - 1, 2008 blob_op_complete, NULL); 2009 poll_threads(); 2010 CU_ASSERT(g_bserrno == 0); 2011 2012 /* Write last page with a pattern */ 2013 spdk_blob_io_write(blob, channel, payload_pattern, pages_per_payload - 1, 1, 2014 blob_op_complete, NULL); 2015 poll_threads(); 2016 CU_ASSERT(g_bserrno == 0); 2017 2018 /* Read whole blob and check consistency */ 2019 memset(payload_read, 0xFF, payload_size); 2020 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 2021 poll_threads(); 2022 CU_ASSERT(g_bserrno == 0); 2023 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0); 2024 CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0); 2025 2026 /* Fill whole blob except first page */ 2027 spdk_blob_io_write(blob, channel, payload_pattern, 1, pages_per_payload - 1, 2028 blob_op_complete, NULL); 2029 poll_threads(); 2030 CU_ASSERT(g_bserrno == 0); 2031 2032 /* Write first page with a pattern */ 2033 spdk_blob_io_write(blob, channel, payload_pattern, 0, 1, 2034 blob_op_complete, NULL); 2035 poll_threads(); 2036 CU_ASSERT(g_bserrno == 0); 2037 2038 /* Read whole blob and check consistency */ 2039 memset(payload_read, 0xFF, payload_size); 2040 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 2041 poll_threads(); 2042 CU_ASSERT(g_bserrno == 0); 2043 CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0); 2044 CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0); 2045 2046 2047 /* Fill whole blob with a pattern (5 clusters) */ 2048 2049 /* 1. Read test. */ 2050 _blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload, 2051 blob_op_complete, NULL); 2052 poll_threads(); 2053 CU_ASSERT(g_bserrno == 0); 2054 2055 memset(payload_read, 0xFF, payload_size); 2056 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 2057 poll_threads(); 2058 poll_threads(); 2059 CU_ASSERT(g_bserrno == 0); 2060 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 2061 2062 /* 2. Write test. */ 2063 spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload, 2064 blob_op_complete, NULL); 2065 poll_threads(); 2066 CU_ASSERT(g_bserrno == 0); 2067 2068 memset(payload_read, 0xFF, payload_size); 2069 _blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 2070 poll_threads(); 2071 CU_ASSERT(g_bserrno == 0); 2072 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 2073 2074 spdk_blob_close(blob, blob_op_complete, NULL); 2075 poll_threads(); 2076 CU_ASSERT(g_bserrno == 0); 2077 2078 spdk_bs_free_io_channel(channel); 2079 poll_threads(); 2080 2081 /* Unload the blob store */ 2082 spdk_bs_unload(bs, bs_op_complete, NULL); 2083 poll_threads(); 2084 CU_ASSERT(g_bserrno == 0); 2085 g_bs = NULL; 2086 g_blob = NULL; 2087 g_blobid = 0; 2088 2089 free(payload_read); 2090 free(payload_write); 2091 free(payload_pattern); 2092 } 2093 2094 static void 2095 blob_operation_split_rw_iov(void) 2096 { 2097 struct spdk_blob_store *bs; 2098 struct spdk_bs_dev *dev; 2099 struct spdk_blob *blob; 2100 struct spdk_io_channel *channel; 2101 struct spdk_blob_opts opts; 2102 spdk_blob_id blobid; 2103 uint64_t cluster_size; 2104 2105 uint64_t payload_size; 2106 uint8_t *payload_read; 2107 uint8_t *payload_write; 2108 uint8_t *payload_pattern; 2109 2110 uint64_t page_size; 2111 uint64_t pages_per_cluster; 2112 uint64_t pages_per_payload; 2113 2114 struct iovec iov_read[2]; 2115 struct iovec iov_write[2]; 2116 2117 uint64_t i, j; 2118 2119 dev = init_dev(); 2120 2121 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2122 poll_threads(); 2123 CU_ASSERT(g_bserrno == 0); 2124 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2125 bs = g_bs; 2126 2127 cluster_size = spdk_bs_get_cluster_size(bs); 2128 page_size = spdk_bs_get_page_size(bs); 2129 pages_per_cluster = cluster_size / page_size; 2130 pages_per_payload = pages_per_cluster * 5; 2131 payload_size = cluster_size * 5; 2132 2133 payload_read = malloc(payload_size); 2134 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 2135 2136 payload_write = malloc(payload_size); 2137 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 2138 2139 payload_pattern = malloc(payload_size); 2140 SPDK_CU_ASSERT_FATAL(payload_pattern != NULL); 2141 2142 /* Prepare random pattern to write */ 2143 for (i = 0; i < pages_per_payload; i++) { 2144 for (j = 0; j < page_size / sizeof(uint64_t); j++) { 2145 uint64_t *tmp; 2146 2147 tmp = (uint64_t *)payload_pattern; 2148 tmp += ((page_size * i) / sizeof(uint64_t)) + j; 2149 *tmp = i + 1; 2150 } 2151 } 2152 2153 channel = spdk_bs_alloc_io_channel(bs); 2154 SPDK_CU_ASSERT_FATAL(channel != NULL); 2155 2156 /* Create blob */ 2157 ut_spdk_blob_opts_init(&opts); 2158 opts.thin_provision = false; 2159 opts.num_clusters = 5; 2160 2161 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2162 poll_threads(); 2163 CU_ASSERT(g_bserrno == 0); 2164 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2165 blobid = g_blobid; 2166 2167 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2168 poll_threads(); 2169 CU_ASSERT(g_bserrno == 0); 2170 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2171 blob = g_blob; 2172 2173 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 2174 2175 /* Initial read should return zeroes payload */ 2176 memset(payload_read, 0xFF, payload_size); 2177 iov_read[0].iov_base = payload_read; 2178 iov_read[0].iov_len = cluster_size * 3; 2179 iov_read[1].iov_base = payload_read + cluster_size * 3; 2180 iov_read[1].iov_len = cluster_size * 2; 2181 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 2182 poll_threads(); 2183 CU_ASSERT(g_bserrno == 0); 2184 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 2185 2186 /* First of iovs fills whole blob except last page and second of iovs writes last page 2187 * with a pattern. */ 2188 iov_write[0].iov_base = payload_pattern; 2189 iov_write[0].iov_len = payload_size - page_size; 2190 iov_write[1].iov_base = payload_pattern; 2191 iov_write[1].iov_len = page_size; 2192 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 2193 poll_threads(); 2194 CU_ASSERT(g_bserrno == 0); 2195 2196 /* Read whole blob and check consistency */ 2197 memset(payload_read, 0xFF, payload_size); 2198 iov_read[0].iov_base = payload_read; 2199 iov_read[0].iov_len = cluster_size * 2; 2200 iov_read[1].iov_base = payload_read + cluster_size * 2; 2201 iov_read[1].iov_len = cluster_size * 3; 2202 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 2203 poll_threads(); 2204 CU_ASSERT(g_bserrno == 0); 2205 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0); 2206 CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0); 2207 2208 /* First of iovs fills only first page and second of iovs writes whole blob except 2209 * first page with a pattern. */ 2210 iov_write[0].iov_base = payload_pattern; 2211 iov_write[0].iov_len = page_size; 2212 iov_write[1].iov_base = payload_pattern; 2213 iov_write[1].iov_len = payload_size - page_size; 2214 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 2215 poll_threads(); 2216 CU_ASSERT(g_bserrno == 0); 2217 2218 /* Read whole blob and check consistency */ 2219 memset(payload_read, 0xFF, payload_size); 2220 iov_read[0].iov_base = payload_read; 2221 iov_read[0].iov_len = cluster_size * 4; 2222 iov_read[1].iov_base = payload_read + cluster_size * 4; 2223 iov_read[1].iov_len = cluster_size; 2224 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 2225 poll_threads(); 2226 CU_ASSERT(g_bserrno == 0); 2227 CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0); 2228 CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0); 2229 2230 2231 /* Fill whole blob with a pattern (5 clusters) */ 2232 2233 /* 1. Read test. */ 2234 _blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload, 2235 blob_op_complete, NULL); 2236 poll_threads(); 2237 CU_ASSERT(g_bserrno == 0); 2238 2239 memset(payload_read, 0xFF, payload_size); 2240 iov_read[0].iov_base = payload_read; 2241 iov_read[0].iov_len = cluster_size; 2242 iov_read[1].iov_base = payload_read + cluster_size; 2243 iov_read[1].iov_len = cluster_size * 4; 2244 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 2245 poll_threads(); 2246 CU_ASSERT(g_bserrno == 0); 2247 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 2248 2249 /* 2. Write test. */ 2250 iov_write[0].iov_base = payload_read; 2251 iov_write[0].iov_len = cluster_size * 2; 2252 iov_write[1].iov_base = payload_read + cluster_size * 2; 2253 iov_write[1].iov_len = cluster_size * 3; 2254 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 2255 poll_threads(); 2256 CU_ASSERT(g_bserrno == 0); 2257 2258 memset(payload_read, 0xFF, payload_size); 2259 _blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 2260 poll_threads(); 2261 CU_ASSERT(g_bserrno == 0); 2262 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 2263 2264 spdk_blob_close(blob, blob_op_complete, NULL); 2265 CU_ASSERT(g_bserrno == 0); 2266 2267 spdk_bs_free_io_channel(channel); 2268 poll_threads(); 2269 2270 /* Unload the blob store */ 2271 spdk_bs_unload(bs, bs_op_complete, NULL); 2272 poll_threads(); 2273 CU_ASSERT(g_bserrno == 0); 2274 g_bs = NULL; 2275 g_blob = NULL; 2276 g_blobid = 0; 2277 2278 free(payload_read); 2279 free(payload_write); 2280 free(payload_pattern); 2281 } 2282 2283 static void 2284 blob_unmap(void) 2285 { 2286 struct spdk_blob_store *bs; 2287 struct spdk_bs_dev *dev; 2288 struct spdk_blob *blob; 2289 struct spdk_io_channel *channel; 2290 spdk_blob_id blobid; 2291 struct spdk_blob_opts opts; 2292 uint8_t payload[4096]; 2293 int i; 2294 2295 dev = init_dev(); 2296 2297 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2298 poll_threads(); 2299 CU_ASSERT(g_bserrno == 0); 2300 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2301 bs = g_bs; 2302 2303 channel = spdk_bs_alloc_io_channel(bs); 2304 CU_ASSERT(channel != NULL); 2305 2306 ut_spdk_blob_opts_init(&opts); 2307 opts.num_clusters = 10; 2308 2309 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2310 poll_threads(); 2311 CU_ASSERT(g_bserrno == 0); 2312 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2313 blobid = g_blobid; 2314 2315 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2316 poll_threads(); 2317 CU_ASSERT(g_bserrno == 0); 2318 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2319 blob = g_blob; 2320 2321 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2322 poll_threads(); 2323 CU_ASSERT(g_bserrno == 0); 2324 2325 memset(payload, 0, sizeof(payload)); 2326 payload[0] = 0xFF; 2327 2328 /* 2329 * Set first byte of every cluster to 0xFF. 2330 * First cluster on device is reserved so let's start from cluster number 1 2331 */ 2332 for (i = 1; i < 11; i++) { 2333 g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF; 2334 } 2335 2336 /* Confirm writes */ 2337 for (i = 0; i < 10; i++) { 2338 payload[0] = 0; 2339 spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1, 2340 blob_op_complete, NULL); 2341 poll_threads(); 2342 CU_ASSERT(g_bserrno == 0); 2343 CU_ASSERT(payload[0] == 0xFF); 2344 } 2345 2346 /* Mark some clusters as unallocated */ 2347 blob->active.clusters[1] = 0; 2348 blob->active.clusters[2] = 0; 2349 blob->active.clusters[3] = 0; 2350 blob->active.clusters[6] = 0; 2351 blob->active.clusters[8] = 0; 2352 2353 /* Unmap clusters by resizing to 0 */ 2354 spdk_blob_resize(blob, 0, blob_op_complete, NULL); 2355 poll_threads(); 2356 CU_ASSERT(g_bserrno == 0); 2357 2358 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2359 poll_threads(); 2360 CU_ASSERT(g_bserrno == 0); 2361 2362 /* Confirm that only 'allocated' clusters were unmapped */ 2363 for (i = 1; i < 11; i++) { 2364 switch (i) { 2365 case 2: 2366 case 3: 2367 case 4: 2368 case 7: 2369 case 9: 2370 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF); 2371 break; 2372 default: 2373 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0); 2374 break; 2375 } 2376 } 2377 2378 spdk_blob_close(blob, blob_op_complete, NULL); 2379 poll_threads(); 2380 CU_ASSERT(g_bserrno == 0); 2381 2382 spdk_bs_free_io_channel(channel); 2383 poll_threads(); 2384 2385 spdk_bs_unload(bs, bs_op_complete, NULL); 2386 poll_threads(); 2387 CU_ASSERT(g_bserrno == 0); 2388 g_bs = NULL; 2389 } 2390 2391 2392 static void 2393 blob_iter(void) 2394 { 2395 struct spdk_blob_store *bs; 2396 struct spdk_bs_dev *dev; 2397 struct spdk_blob *blob; 2398 spdk_blob_id blobid; 2399 struct spdk_blob_opts blob_opts; 2400 2401 dev = init_dev(); 2402 2403 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2404 poll_threads(); 2405 CU_ASSERT(g_bserrno == 0); 2406 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2407 bs = g_bs; 2408 2409 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 2410 poll_threads(); 2411 CU_ASSERT(g_blob == NULL); 2412 CU_ASSERT(g_bserrno == -ENOENT); 2413 2414 ut_spdk_blob_opts_init(&blob_opts); 2415 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 2416 poll_threads(); 2417 CU_ASSERT(g_bserrno == 0); 2418 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2419 blobid = g_blobid; 2420 2421 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 2422 poll_threads(); 2423 CU_ASSERT(g_blob != NULL); 2424 CU_ASSERT(g_bserrno == 0); 2425 blob = g_blob; 2426 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 2427 2428 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 2429 poll_threads(); 2430 CU_ASSERT(g_blob == NULL); 2431 CU_ASSERT(g_bserrno == -ENOENT); 2432 2433 spdk_bs_unload(bs, bs_op_complete, NULL); 2434 poll_threads(); 2435 CU_ASSERT(g_bserrno == 0); 2436 g_bs = NULL; 2437 } 2438 2439 static void 2440 blob_xattr(void) 2441 { 2442 struct spdk_blob_store *bs; 2443 struct spdk_bs_dev *dev; 2444 struct spdk_blob *blob; 2445 struct spdk_blob_opts blob_opts; 2446 spdk_blob_id blobid; 2447 uint64_t length; 2448 int rc; 2449 const char *name1, *name2; 2450 const void *value; 2451 size_t value_len; 2452 struct spdk_xattr_names *names; 2453 2454 dev = init_dev(); 2455 2456 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2457 poll_threads(); 2458 CU_ASSERT(g_bserrno == 0); 2459 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2460 bs = g_bs; 2461 2462 ut_spdk_blob_opts_init(&blob_opts); 2463 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 2464 poll_threads(); 2465 CU_ASSERT(g_bserrno == 0); 2466 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2467 blobid = g_blobid; 2468 2469 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2470 poll_threads(); 2471 CU_ASSERT(g_bserrno == 0); 2472 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2473 blob = g_blob; 2474 2475 /* Test that set_xattr fails if md_ro flag is set. */ 2476 blob->md_ro = true; 2477 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2478 CU_ASSERT(rc == -EPERM); 2479 2480 blob->md_ro = false; 2481 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2482 CU_ASSERT(rc == 0); 2483 2484 length = 2345; 2485 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2486 CU_ASSERT(rc == 0); 2487 2488 /* Overwrite "length" xattr. */ 2489 length = 3456; 2490 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2491 CU_ASSERT(rc == 0); 2492 2493 /* get_xattr should still work even if md_ro flag is set. */ 2494 value = NULL; 2495 blob->md_ro = true; 2496 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2497 CU_ASSERT(rc == 0); 2498 SPDK_CU_ASSERT_FATAL(value != NULL); 2499 CU_ASSERT(*(uint64_t *)value == length); 2500 CU_ASSERT(value_len == 8); 2501 blob->md_ro = false; 2502 2503 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2504 CU_ASSERT(rc == -ENOENT); 2505 2506 names = NULL; 2507 rc = spdk_blob_get_xattr_names(blob, &names); 2508 CU_ASSERT(rc == 0); 2509 SPDK_CU_ASSERT_FATAL(names != NULL); 2510 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 2511 name1 = spdk_xattr_names_get_name(names, 0); 2512 SPDK_CU_ASSERT_FATAL(name1 != NULL); 2513 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 2514 name2 = spdk_xattr_names_get_name(names, 1); 2515 SPDK_CU_ASSERT_FATAL(name2 != NULL); 2516 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 2517 CU_ASSERT(strcmp(name1, name2)); 2518 spdk_xattr_names_free(names); 2519 2520 /* Confirm that remove_xattr fails if md_ro is set to true. */ 2521 blob->md_ro = true; 2522 rc = spdk_blob_remove_xattr(blob, "name"); 2523 CU_ASSERT(rc == -EPERM); 2524 2525 blob->md_ro = false; 2526 rc = spdk_blob_remove_xattr(blob, "name"); 2527 CU_ASSERT(rc == 0); 2528 2529 rc = spdk_blob_remove_xattr(blob, "foobar"); 2530 CU_ASSERT(rc == -ENOENT); 2531 2532 /* Set internal xattr */ 2533 length = 7898; 2534 rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true); 2535 CU_ASSERT(rc == 0); 2536 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 2537 CU_ASSERT(rc == 0); 2538 CU_ASSERT(*(uint64_t *)value == length); 2539 /* try to get public xattr with same name */ 2540 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 2541 CU_ASSERT(rc != 0); 2542 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false); 2543 CU_ASSERT(rc != 0); 2544 /* Check if SPDK_BLOB_INTERNAL_XATTR is set */ 2545 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 2546 SPDK_BLOB_INTERNAL_XATTR); 2547 2548 spdk_blob_close(blob, blob_op_complete, NULL); 2549 poll_threads(); 2550 2551 spdk_bs_unload(bs, bs_op_complete, NULL); 2552 poll_threads(); 2553 2554 /* Check if xattrs are persisted */ 2555 dev = init_dev(); 2556 2557 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2558 poll_threads(); 2559 CU_ASSERT(g_bserrno == 0); 2560 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2561 2562 bs = g_bs; 2563 2564 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2565 poll_threads(); 2566 CU_ASSERT(g_bserrno == 0); 2567 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2568 blob = g_blob; 2569 2570 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 2571 CU_ASSERT(rc == 0); 2572 CU_ASSERT(*(uint64_t *)value == length); 2573 2574 /* try to get internal xattr trough public call */ 2575 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 2576 CU_ASSERT(rc != 0); 2577 2578 rc = _spdk_blob_remove_xattr(blob, "internal", true); 2579 CU_ASSERT(rc == 0); 2580 2581 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0); 2582 2583 spdk_blob_close(blob, blob_op_complete, NULL); 2584 poll_threads(); 2585 CU_ASSERT(g_bserrno == 0); 2586 2587 spdk_bs_unload(bs, bs_op_complete, NULL); 2588 poll_threads(); 2589 CU_ASSERT(g_bserrno == 0); 2590 g_bs = NULL; 2591 } 2592 2593 static void 2594 bs_load(void) 2595 { 2596 struct spdk_blob_store *bs; 2597 struct spdk_bs_dev *dev; 2598 spdk_blob_id blobid; 2599 struct spdk_blob *blob; 2600 struct spdk_bs_super_block *super_block; 2601 uint64_t length; 2602 int rc; 2603 const void *value; 2604 size_t value_len; 2605 struct spdk_bs_opts opts; 2606 struct spdk_blob_opts blob_opts; 2607 2608 dev = init_dev(); 2609 spdk_bs_opts_init(&opts); 2610 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2611 2612 /* Initialize a new blob store */ 2613 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2614 poll_threads(); 2615 CU_ASSERT(g_bserrno == 0); 2616 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2617 bs = g_bs; 2618 2619 /* Try to open a blobid that does not exist */ 2620 spdk_bs_open_blob(bs, 0, blob_op_with_handle_complete, NULL); 2621 poll_threads(); 2622 CU_ASSERT(g_bserrno == -ENOENT); 2623 CU_ASSERT(g_blob == NULL); 2624 2625 /* Create a blob */ 2626 ut_spdk_blob_opts_init(&blob_opts); 2627 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 2628 poll_threads(); 2629 CU_ASSERT(g_bserrno == 0); 2630 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2631 blobid = g_blobid; 2632 2633 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2634 poll_threads(); 2635 CU_ASSERT(g_bserrno == 0); 2636 CU_ASSERT(g_blob != NULL); 2637 blob = g_blob; 2638 2639 /* Try again to open valid blob but without the upper bit set */ 2640 spdk_bs_open_blob(bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 2641 poll_threads(); 2642 CU_ASSERT(g_bserrno == -ENOENT); 2643 CU_ASSERT(g_blob == NULL); 2644 2645 /* Set some xattrs */ 2646 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2647 CU_ASSERT(rc == 0); 2648 2649 length = 2345; 2650 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2651 CU_ASSERT(rc == 0); 2652 2653 /* Resize the blob */ 2654 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2655 poll_threads(); 2656 CU_ASSERT(g_bserrno == 0); 2657 2658 spdk_blob_close(blob, blob_op_complete, NULL); 2659 poll_threads(); 2660 CU_ASSERT(g_bserrno == 0); 2661 blob = NULL; 2662 g_blob = NULL; 2663 g_blobid = SPDK_BLOBID_INVALID; 2664 2665 /* Unload the blob store */ 2666 spdk_bs_unload(bs, bs_op_complete, NULL); 2667 poll_threads(); 2668 CU_ASSERT(g_bserrno == 0); 2669 g_bs = NULL; 2670 g_blob = NULL; 2671 g_blobid = 0; 2672 2673 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2674 CU_ASSERT(super_block->clean == 1); 2675 2676 /* Load should fail for device with an unsupported blocklen */ 2677 dev = init_dev(); 2678 dev->blocklen = SPDK_BS_PAGE_SIZE * 2; 2679 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2680 poll_threads(); 2681 CU_ASSERT(g_bserrno == -EINVAL); 2682 2683 /* Load should when max_md_ops is set to zero */ 2684 dev = init_dev(); 2685 spdk_bs_opts_init(&opts); 2686 opts.max_md_ops = 0; 2687 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2688 poll_threads(); 2689 CU_ASSERT(g_bserrno == -EINVAL); 2690 2691 /* Load should when max_channel_ops is set to zero */ 2692 dev = init_dev(); 2693 spdk_bs_opts_init(&opts); 2694 opts.max_channel_ops = 0; 2695 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2696 poll_threads(); 2697 CU_ASSERT(g_bserrno == -EINVAL); 2698 2699 /* Load an existing blob store */ 2700 dev = init_dev(); 2701 spdk_bs_opts_init(&opts); 2702 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2703 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2704 poll_threads(); 2705 CU_ASSERT(g_bserrno == 0); 2706 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2707 bs = g_bs; 2708 2709 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2710 CU_ASSERT(super_block->clean == 1); 2711 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2712 2713 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2714 poll_threads(); 2715 CU_ASSERT(g_bserrno == 0); 2716 CU_ASSERT(g_blob != NULL); 2717 blob = g_blob; 2718 2719 /* Verify that blobstore is marked dirty after first metadata sync */ 2720 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2721 CU_ASSERT(super_block->clean == 1); 2722 2723 /* Get the xattrs */ 2724 value = NULL; 2725 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2726 CU_ASSERT(rc == 0); 2727 SPDK_CU_ASSERT_FATAL(value != NULL); 2728 CU_ASSERT(*(uint64_t *)value == length); 2729 CU_ASSERT(value_len == 8); 2730 2731 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2732 CU_ASSERT(rc == -ENOENT); 2733 2734 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2735 2736 spdk_blob_close(blob, blob_op_complete, NULL); 2737 poll_threads(); 2738 CU_ASSERT(g_bserrno == 0); 2739 blob = NULL; 2740 g_blob = NULL; 2741 2742 spdk_bs_unload(bs, bs_op_complete, NULL); 2743 poll_threads(); 2744 CU_ASSERT(g_bserrno == 0); 2745 g_bs = NULL; 2746 2747 /* Load should fail: bdev size < saved size */ 2748 dev = init_dev(); 2749 dev->blockcnt /= 2; 2750 2751 spdk_bs_opts_init(&opts); 2752 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2753 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2754 poll_threads(); 2755 2756 CU_ASSERT(g_bserrno == -EILSEQ); 2757 2758 /* Load should succeed: bdev size > saved size */ 2759 dev = init_dev(); 2760 dev->blockcnt *= 4; 2761 2762 spdk_bs_opts_init(&opts); 2763 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2764 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2765 poll_threads(); 2766 CU_ASSERT(g_bserrno == 0); 2767 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2768 bs = g_bs; 2769 2770 CU_ASSERT(g_bserrno == 0); 2771 spdk_bs_unload(bs, bs_op_complete, NULL); 2772 poll_threads(); 2773 2774 2775 /* Test compatibility mode */ 2776 2777 dev = init_dev(); 2778 super_block->size = 0; 2779 super_block->crc = _spdk_blob_md_page_calc_crc(super_block); 2780 2781 spdk_bs_opts_init(&opts); 2782 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2783 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2784 poll_threads(); 2785 CU_ASSERT(g_bserrno == 0); 2786 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2787 bs = g_bs; 2788 2789 /* Create a blob */ 2790 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 2791 poll_threads(); 2792 CU_ASSERT(g_bserrno == 0); 2793 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2794 2795 /* Blobstore should update number of blocks in super_block */ 2796 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2797 CU_ASSERT(super_block->clean == 0); 2798 2799 spdk_bs_unload(bs, bs_op_complete, NULL); 2800 poll_threads(); 2801 CU_ASSERT(g_bserrno == 0); 2802 CU_ASSERT(super_block->clean == 1); 2803 g_bs = NULL; 2804 2805 } 2806 2807 static void 2808 bs_load_pending_removal(void) 2809 { 2810 struct spdk_blob_store *bs; 2811 struct spdk_bs_dev *dev; 2812 struct spdk_blob_opts opts; 2813 struct spdk_blob *blob, *snapshot; 2814 spdk_blob_id blobid, snapshotid; 2815 const void *value; 2816 size_t value_len; 2817 int rc; 2818 2819 dev = init_dev(); 2820 2821 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2822 poll_threads(); 2823 CU_ASSERT(g_bserrno == 0); 2824 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2825 bs = g_bs; 2826 2827 /* Create blob */ 2828 ut_spdk_blob_opts_init(&opts); 2829 opts.num_clusters = 10; 2830 2831 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2832 poll_threads(); 2833 CU_ASSERT(g_bserrno == 0); 2834 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2835 blobid = g_blobid; 2836 2837 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2838 poll_threads(); 2839 CU_ASSERT(g_bserrno == 0); 2840 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2841 blob = g_blob; 2842 2843 /* Create snapshot */ 2844 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 2845 poll_threads(); 2846 CU_ASSERT(g_bserrno == 0); 2847 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2848 snapshotid = g_blobid; 2849 2850 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 2851 poll_threads(); 2852 CU_ASSERT(g_bserrno == 0); 2853 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2854 snapshot = g_blob; 2855 2856 /* Set SNAPSHOT_PENDING_REMOVAL xattr */ 2857 snapshot->md_ro = false; 2858 rc = _spdk_blob_set_xattr(snapshot, SNAPSHOT_PENDING_REMOVAL, &blobid, sizeof(spdk_blob_id), true); 2859 CU_ASSERT(rc == 0); 2860 snapshot->md_ro = true; 2861 2862 spdk_blob_close(snapshot, blob_op_complete, NULL); 2863 poll_threads(); 2864 CU_ASSERT(g_bserrno == 0); 2865 2866 spdk_blob_close(blob, blob_op_complete, NULL); 2867 poll_threads(); 2868 CU_ASSERT(g_bserrno == 0); 2869 2870 /* Reload blobstore */ 2871 spdk_bs_unload(bs, bs_op_complete, NULL); 2872 poll_threads(); 2873 CU_ASSERT(g_bserrno == 0); 2874 g_bs = NULL; 2875 2876 dev = init_dev(); 2877 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2878 poll_threads(); 2879 CU_ASSERT(g_bserrno == 0); 2880 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2881 bs = g_bs; 2882 2883 /* Snapshot should not be removed as blob is still pointing to it */ 2884 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 2885 poll_threads(); 2886 CU_ASSERT(g_bserrno == 0); 2887 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2888 snapshot = g_blob; 2889 2890 /* SNAPSHOT_PENDING_REMOVAL xattr should be removed during load */ 2891 rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_PENDING_REMOVAL, &value, &value_len); 2892 CU_ASSERT(rc != 0); 2893 2894 /* Set SNAPSHOT_PENDING_REMOVAL xattr again */ 2895 snapshot->md_ro = false; 2896 rc = _spdk_blob_set_xattr(snapshot, SNAPSHOT_PENDING_REMOVAL, &blobid, sizeof(spdk_blob_id), true); 2897 CU_ASSERT(rc == 0); 2898 snapshot->md_ro = true; 2899 2900 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2901 poll_threads(); 2902 CU_ASSERT(g_bserrno == 0); 2903 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2904 blob = g_blob; 2905 2906 /* Remove parent_id from blob by removing BLOB_SNAPSHOT xattr */ 2907 _spdk_blob_remove_xattr(blob, BLOB_SNAPSHOT, true); 2908 2909 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2910 poll_threads(); 2911 CU_ASSERT(g_bserrno == 0); 2912 2913 spdk_blob_close(snapshot, blob_op_complete, NULL); 2914 poll_threads(); 2915 CU_ASSERT(g_bserrno == 0); 2916 2917 spdk_blob_close(blob, blob_op_complete, NULL); 2918 poll_threads(); 2919 CU_ASSERT(g_bserrno == 0); 2920 2921 /* Reload blobstore */ 2922 spdk_bs_unload(bs, bs_op_complete, NULL); 2923 poll_threads(); 2924 CU_ASSERT(g_bserrno == 0); 2925 g_bs = NULL; 2926 2927 dev = init_dev(); 2928 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2929 poll_threads(); 2930 CU_ASSERT(g_bserrno == 0); 2931 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2932 bs = g_bs; 2933 2934 /* Snapshot should be removed as blob is not pointing to it anymore */ 2935 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 2936 poll_threads(); 2937 CU_ASSERT(g_bserrno != 0); 2938 2939 spdk_bs_unload(bs, bs_op_complete, NULL); 2940 poll_threads(); 2941 CU_ASSERT(g_bserrno == 0); 2942 g_bs = NULL; 2943 } 2944 2945 static void 2946 bs_load_custom_cluster_size(void) 2947 { 2948 struct spdk_blob_store *bs; 2949 struct spdk_bs_dev *dev; 2950 struct spdk_bs_super_block *super_block; 2951 struct spdk_bs_opts opts; 2952 uint32_t custom_cluster_size = 4194304; /* 4MiB */ 2953 uint32_t cluster_sz; 2954 uint64_t total_clusters; 2955 2956 dev = init_dev(); 2957 spdk_bs_opts_init(&opts); 2958 opts.cluster_sz = custom_cluster_size; 2959 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2960 2961 /* Initialize a new blob store */ 2962 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2963 poll_threads(); 2964 CU_ASSERT(g_bserrno == 0); 2965 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2966 bs = g_bs; 2967 cluster_sz = g_bs->cluster_sz; 2968 total_clusters = g_bs->total_clusters; 2969 2970 /* Unload the blob store */ 2971 spdk_bs_unload(bs, bs_op_complete, NULL); 2972 poll_threads(); 2973 CU_ASSERT(g_bserrno == 0); 2974 g_bs = NULL; 2975 g_blob = NULL; 2976 g_blobid = 0; 2977 2978 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2979 CU_ASSERT(super_block->clean == 1); 2980 2981 /* Load an existing blob store */ 2982 dev = init_dev(); 2983 spdk_bs_opts_init(&opts); 2984 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2985 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2986 poll_threads(); 2987 CU_ASSERT(g_bserrno == 0); 2988 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2989 bs = g_bs; 2990 /* Compare cluster size and number to one after initialization */ 2991 CU_ASSERT(cluster_sz == g_bs->cluster_sz); 2992 CU_ASSERT(total_clusters == g_bs->total_clusters); 2993 2994 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2995 CU_ASSERT(super_block->clean == 1); 2996 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2997 2998 spdk_bs_unload(bs, bs_op_complete, NULL); 2999 poll_threads(); 3000 CU_ASSERT(g_bserrno == 0); 3001 CU_ASSERT(super_block->clean == 1); 3002 g_bs = NULL; 3003 } 3004 3005 static void 3006 bs_type(void) 3007 { 3008 struct spdk_blob_store *bs; 3009 struct spdk_bs_dev *dev; 3010 struct spdk_bs_opts opts; 3011 3012 dev = init_dev(); 3013 spdk_bs_opts_init(&opts); 3014 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3015 3016 /* Initialize a new blob store */ 3017 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3018 poll_threads(); 3019 CU_ASSERT(g_bserrno == 0); 3020 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3021 bs = g_bs; 3022 3023 /* Unload the blob store */ 3024 spdk_bs_unload(bs, bs_op_complete, NULL); 3025 poll_threads(); 3026 CU_ASSERT(g_bserrno == 0); 3027 g_bs = NULL; 3028 g_blob = NULL; 3029 g_blobid = 0; 3030 3031 /* Load non existing blobstore type */ 3032 dev = init_dev(); 3033 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 3034 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3035 poll_threads(); 3036 CU_ASSERT(g_bserrno != 0); 3037 3038 /* Load with empty blobstore type */ 3039 dev = init_dev(); 3040 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 3041 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3042 poll_threads(); 3043 CU_ASSERT(g_bserrno == 0); 3044 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3045 bs = g_bs; 3046 3047 spdk_bs_unload(bs, bs_op_complete, NULL); 3048 poll_threads(); 3049 CU_ASSERT(g_bserrno == 0); 3050 g_bs = NULL; 3051 3052 /* Initialize a new blob store with empty bstype */ 3053 dev = init_dev(); 3054 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 3055 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3056 poll_threads(); 3057 CU_ASSERT(g_bserrno == 0); 3058 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3059 bs = g_bs; 3060 3061 spdk_bs_unload(bs, bs_op_complete, NULL); 3062 poll_threads(); 3063 CU_ASSERT(g_bserrno == 0); 3064 g_bs = NULL; 3065 3066 /* Load non existing blobstore type */ 3067 dev = init_dev(); 3068 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 3069 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3070 poll_threads(); 3071 CU_ASSERT(g_bserrno != 0); 3072 3073 /* Load with empty blobstore type */ 3074 dev = init_dev(); 3075 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 3076 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3077 poll_threads(); 3078 CU_ASSERT(g_bserrno == 0); 3079 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3080 bs = g_bs; 3081 3082 spdk_bs_unload(bs, bs_op_complete, NULL); 3083 poll_threads(); 3084 CU_ASSERT(g_bserrno == 0); 3085 g_bs = NULL; 3086 } 3087 3088 static void 3089 bs_super_block(void) 3090 { 3091 struct spdk_blob_store *bs; 3092 struct spdk_bs_dev *dev; 3093 struct spdk_bs_super_block *super_block; 3094 struct spdk_bs_opts opts; 3095 struct spdk_bs_super_block_ver1 super_block_v1; 3096 3097 dev = init_dev(); 3098 spdk_bs_opts_init(&opts); 3099 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3100 3101 /* Initialize a new blob store */ 3102 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3103 poll_threads(); 3104 CU_ASSERT(g_bserrno == 0); 3105 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3106 bs = g_bs; 3107 3108 /* Unload the blob store */ 3109 spdk_bs_unload(bs, bs_op_complete, NULL); 3110 poll_threads(); 3111 CU_ASSERT(g_bserrno == 0); 3112 g_bs = NULL; 3113 g_blob = NULL; 3114 g_blobid = 0; 3115 3116 /* Load an existing blob store with version newer than supported */ 3117 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 3118 super_block->version++; 3119 3120 dev = init_dev(); 3121 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 3122 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3123 poll_threads(); 3124 CU_ASSERT(g_bserrno != 0); 3125 3126 /* Create a new blob store with super block version 1 */ 3127 dev = init_dev(); 3128 super_block_v1.version = 1; 3129 memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 3130 super_block_v1.length = 0x1000; 3131 super_block_v1.clean = 1; 3132 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 3133 super_block_v1.cluster_size = 0x100000; 3134 super_block_v1.used_page_mask_start = 0x01; 3135 super_block_v1.used_page_mask_len = 0x01; 3136 super_block_v1.used_cluster_mask_start = 0x02; 3137 super_block_v1.used_cluster_mask_len = 0x01; 3138 super_block_v1.md_start = 0x03; 3139 super_block_v1.md_len = 0x40; 3140 memset(super_block_v1.reserved, 0, 4036); 3141 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 3142 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 3143 3144 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 3145 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3146 poll_threads(); 3147 CU_ASSERT(g_bserrno == 0); 3148 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3149 bs = g_bs; 3150 3151 spdk_bs_unload(bs, bs_op_complete, NULL); 3152 poll_threads(); 3153 CU_ASSERT(g_bserrno == 0); 3154 g_bs = NULL; 3155 } 3156 3157 /* 3158 * Create a blobstore and then unload it. 3159 */ 3160 static void 3161 bs_unload(void) 3162 { 3163 struct spdk_bs_dev *dev; 3164 struct spdk_blob_store *bs; 3165 spdk_blob_id blobid; 3166 struct spdk_blob *blob; 3167 struct spdk_blob_opts blob_opts; 3168 3169 dev = init_dev(); 3170 3171 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3172 poll_threads(); 3173 CU_ASSERT(g_bserrno == 0); 3174 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3175 bs = g_bs; 3176 3177 /* Create a blob and open it. */ 3178 g_bserrno = -1; 3179 ut_spdk_blob_opts_init(&blob_opts); 3180 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3181 poll_threads(); 3182 CU_ASSERT(g_bserrno == 0); 3183 CU_ASSERT(g_blobid > 0); 3184 blobid = g_blobid; 3185 3186 g_bserrno = -1; 3187 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3188 poll_threads(); 3189 CU_ASSERT(g_bserrno == 0); 3190 CU_ASSERT(g_blob != NULL); 3191 blob = g_blob; 3192 3193 /* Try to unload blobstore, should fail with open blob */ 3194 g_bserrno = -1; 3195 spdk_bs_unload(bs, bs_op_complete, NULL); 3196 poll_threads(); 3197 CU_ASSERT(g_bserrno == -EBUSY); 3198 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3199 3200 /* Close the blob, then successfully unload blobstore */ 3201 g_bserrno = -1; 3202 spdk_blob_close(blob, blob_op_complete, NULL); 3203 poll_threads(); 3204 CU_ASSERT(g_bserrno == 0); 3205 3206 g_bserrno = -1; 3207 spdk_bs_unload(bs, bs_op_complete, NULL); 3208 poll_threads(); 3209 CU_ASSERT(g_bserrno == 0); 3210 g_bs = NULL; 3211 } 3212 3213 /* 3214 * Create a blobstore with a cluster size different than the default, and ensure it is 3215 * persisted. 3216 */ 3217 static void 3218 bs_cluster_sz(void) 3219 { 3220 struct spdk_blob_store *bs; 3221 struct spdk_bs_dev *dev; 3222 struct spdk_bs_opts opts; 3223 uint32_t cluster_sz; 3224 3225 /* Set cluster size to zero */ 3226 dev = init_dev(); 3227 spdk_bs_opts_init(&opts); 3228 opts.cluster_sz = 0; 3229 3230 /* Initialize a new blob store */ 3231 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3232 poll_threads(); 3233 CU_ASSERT(g_bserrno == -EINVAL); 3234 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 3235 3236 /* 3237 * Set cluster size to blobstore page size, 3238 * to work it is required to be at least twice the blobstore page size. 3239 */ 3240 dev = init_dev(); 3241 spdk_bs_opts_init(&opts); 3242 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 3243 3244 /* Initialize a new blob store */ 3245 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3246 poll_threads(); 3247 CU_ASSERT(g_bserrno == -ENOMEM); 3248 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 3249 3250 /* 3251 * Set cluster size to lower than page size, 3252 * to work it is required to be at least twice the blobstore page size. 3253 */ 3254 dev = init_dev(); 3255 spdk_bs_opts_init(&opts); 3256 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 3257 3258 /* Initialize a new blob store */ 3259 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3260 poll_threads(); 3261 CU_ASSERT(g_bserrno == -EINVAL); 3262 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 3263 3264 /* Set cluster size to twice the default */ 3265 dev = init_dev(); 3266 spdk_bs_opts_init(&opts); 3267 opts.cluster_sz *= 2; 3268 cluster_sz = opts.cluster_sz; 3269 3270 /* Initialize a new blob store */ 3271 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3272 poll_threads(); 3273 CU_ASSERT(g_bserrno == 0); 3274 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3275 bs = g_bs; 3276 3277 CU_ASSERT(spdk_bs_get_cluster_size(bs) == cluster_sz); 3278 3279 /* Unload the blob store */ 3280 spdk_bs_unload(bs, bs_op_complete, NULL); 3281 poll_threads(); 3282 CU_ASSERT(g_bserrno == 0); 3283 g_bs = NULL; 3284 g_blob = NULL; 3285 g_blobid = 0; 3286 3287 dev = init_dev(); 3288 /* Load an existing blob store */ 3289 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3290 poll_threads(); 3291 CU_ASSERT(g_bserrno == 0); 3292 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3293 bs = g_bs; 3294 3295 CU_ASSERT(spdk_bs_get_cluster_size(bs) == cluster_sz); 3296 3297 spdk_bs_unload(bs, bs_op_complete, NULL); 3298 poll_threads(); 3299 CU_ASSERT(g_bserrno == 0); 3300 g_bs = NULL; 3301 } 3302 3303 /* 3304 * Create a blobstore, reload it and ensure total usable cluster count 3305 * stays the same. 3306 */ 3307 static void 3308 bs_usable_clusters(void) 3309 { 3310 struct spdk_blob_store *bs; 3311 struct spdk_bs_dev *dev; 3312 struct spdk_bs_opts opts; 3313 struct spdk_blob_opts blob_opts; 3314 uint32_t clusters; 3315 int i; 3316 3317 /* Init blobstore */ 3318 dev = init_dev(); 3319 spdk_bs_opts_init(&opts); 3320 3321 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3322 poll_threads(); 3323 CU_ASSERT(g_bserrno == 0); 3324 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3325 bs = g_bs; 3326 3327 clusters = spdk_bs_total_data_cluster_count(bs); 3328 3329 /* Unload the blob store */ 3330 spdk_bs_unload(bs, bs_op_complete, NULL); 3331 poll_threads(); 3332 CU_ASSERT(g_bserrno == 0); 3333 g_bs = NULL; 3334 3335 dev = init_dev(); 3336 /* Load an existing blob store */ 3337 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3338 poll_threads(); 3339 CU_ASSERT(g_bserrno == 0); 3340 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3341 bs = g_bs; 3342 3343 CU_ASSERT(spdk_bs_total_data_cluster_count(bs) == clusters); 3344 ut_spdk_blob_opts_init(&blob_opts); 3345 3346 /* Create and resize blobs to make sure that useable cluster count won't change */ 3347 for (i = 0; i < 4; i++) { 3348 g_bserrno = -1; 3349 g_blobid = SPDK_BLOBID_INVALID; 3350 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3351 poll_threads(); 3352 CU_ASSERT(g_bserrno == 0); 3353 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3354 3355 g_bserrno = -1; 3356 g_blob = NULL; 3357 spdk_bs_open_blob(bs, g_blobid, blob_op_with_handle_complete, NULL); 3358 poll_threads(); 3359 CU_ASSERT(g_bserrno == 0); 3360 CU_ASSERT(g_blob != NULL); 3361 3362 spdk_blob_resize(g_blob, 10, blob_op_complete, NULL); 3363 poll_threads(); 3364 CU_ASSERT(g_bserrno == 0); 3365 3366 g_bserrno = -1; 3367 spdk_blob_close(g_blob, blob_op_complete, NULL); 3368 poll_threads(); 3369 CU_ASSERT(g_bserrno == 0); 3370 3371 CU_ASSERT(spdk_bs_total_data_cluster_count(bs) == clusters); 3372 } 3373 3374 /* Reload the blob store to make sure that nothing changed */ 3375 spdk_bs_unload(bs, bs_op_complete, NULL); 3376 poll_threads(); 3377 CU_ASSERT(g_bserrno == 0); 3378 g_bs = NULL; 3379 3380 dev = init_dev(); 3381 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3382 poll_threads(); 3383 CU_ASSERT(g_bserrno == 0); 3384 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3385 bs = g_bs; 3386 3387 CU_ASSERT(spdk_bs_total_data_cluster_count(bs) == clusters); 3388 3389 spdk_bs_unload(bs, bs_op_complete, NULL); 3390 poll_threads(); 3391 CU_ASSERT(g_bserrno == 0); 3392 g_bs = NULL; 3393 } 3394 3395 /* 3396 * Test resizing of the metadata blob. This requires creating enough blobs 3397 * so that one cluster is not enough to fit the metadata for those blobs. 3398 * To induce this condition to happen more quickly, we reduce the cluster 3399 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 3400 */ 3401 static void 3402 bs_resize_md(void) 3403 { 3404 struct spdk_blob_store *bs; 3405 const int CLUSTER_PAGE_COUNT = 4; 3406 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 3407 struct spdk_bs_dev *dev; 3408 struct spdk_bs_opts opts; 3409 struct spdk_blob_opts blob_opts; 3410 uint32_t cluster_sz; 3411 spdk_blob_id blobids[NUM_BLOBS]; 3412 int i; 3413 3414 3415 dev = init_dev(); 3416 spdk_bs_opts_init(&opts); 3417 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 3418 cluster_sz = opts.cluster_sz; 3419 3420 /* Initialize a new blob store */ 3421 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3422 poll_threads(); 3423 CU_ASSERT(g_bserrno == 0); 3424 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3425 bs = g_bs; 3426 3427 CU_ASSERT(spdk_bs_get_cluster_size(bs) == cluster_sz); 3428 3429 ut_spdk_blob_opts_init(&blob_opts); 3430 3431 for (i = 0; i < NUM_BLOBS; i++) { 3432 g_bserrno = -1; 3433 g_blobid = SPDK_BLOBID_INVALID; 3434 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3435 poll_threads(); 3436 CU_ASSERT(g_bserrno == 0); 3437 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3438 blobids[i] = g_blobid; 3439 } 3440 3441 /* Unload the blob store */ 3442 g_bserrno = -1; 3443 spdk_bs_unload(bs, bs_op_complete, NULL); 3444 poll_threads(); 3445 CU_ASSERT(g_bserrno == 0); 3446 3447 /* Load an existing blob store */ 3448 g_bserrno = -1; 3449 g_bs = NULL; 3450 dev = init_dev(); 3451 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3452 poll_threads(); 3453 CU_ASSERT(g_bserrno == 0); 3454 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3455 bs = g_bs; 3456 3457 CU_ASSERT(spdk_bs_get_cluster_size(bs) == cluster_sz); 3458 3459 for (i = 0; i < NUM_BLOBS; i++) { 3460 g_bserrno = -1; 3461 g_blob = NULL; 3462 spdk_bs_open_blob(bs, blobids[i], blob_op_with_handle_complete, NULL); 3463 poll_threads(); 3464 CU_ASSERT(g_bserrno == 0); 3465 CU_ASSERT(g_blob != NULL); 3466 g_bserrno = -1; 3467 spdk_blob_close(g_blob, blob_op_complete, NULL); 3468 poll_threads(); 3469 CU_ASSERT(g_bserrno == 0); 3470 } 3471 3472 spdk_bs_unload(bs, bs_op_complete, NULL); 3473 poll_threads(); 3474 CU_ASSERT(g_bserrno == 0); 3475 g_bs = NULL; 3476 } 3477 3478 static void 3479 bs_destroy(void) 3480 { 3481 struct spdk_blob_store *bs; 3482 struct spdk_bs_dev *dev; 3483 struct spdk_bs_opts opts; 3484 3485 /* Initialize a new blob store */ 3486 dev = init_dev(); 3487 spdk_bs_opts_init(&opts); 3488 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3489 poll_threads(); 3490 CU_ASSERT(g_bserrno == 0); 3491 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3492 bs = g_bs; 3493 3494 /* Destroy the blob store */ 3495 g_bserrno = -1; 3496 spdk_bs_destroy(bs, bs_op_complete, NULL); 3497 poll_threads(); 3498 CU_ASSERT(g_bserrno == 0); 3499 3500 /* Loading an non-existent blob store should fail. */ 3501 g_bs = NULL; 3502 dev = init_dev(); 3503 3504 g_bserrno = 0; 3505 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3506 poll_threads(); 3507 CU_ASSERT(g_bserrno != 0); 3508 } 3509 3510 /* Try to hit all of the corner cases associated with serializing 3511 * a blob to disk 3512 */ 3513 static void 3514 blob_serialize(void) 3515 { 3516 struct spdk_bs_dev *dev; 3517 struct spdk_bs_opts opts; 3518 struct spdk_blob_store *bs; 3519 struct spdk_blob_opts blob_opts; 3520 spdk_blob_id blobid[2]; 3521 struct spdk_blob *blob[2]; 3522 uint64_t i; 3523 char *value; 3524 int rc; 3525 3526 dev = init_dev(); 3527 3528 /* Initialize a new blobstore with very small clusters */ 3529 spdk_bs_opts_init(&opts); 3530 opts.cluster_sz = dev->blocklen * 8; 3531 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3532 poll_threads(); 3533 CU_ASSERT(g_bserrno == 0); 3534 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3535 bs = g_bs; 3536 ut_spdk_blob_opts_init(&blob_opts); 3537 3538 /* Create and open two blobs */ 3539 for (i = 0; i < 2; i++) { 3540 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3541 poll_threads(); 3542 CU_ASSERT(g_bserrno == 0); 3543 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3544 blobid[i] = g_blobid; 3545 3546 /* Open a blob */ 3547 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 3548 poll_threads(); 3549 CU_ASSERT(g_bserrno == 0); 3550 CU_ASSERT(g_blob != NULL); 3551 blob[i] = g_blob; 3552 3553 /* Set a fairly large xattr on both blobs to eat up 3554 * metadata space 3555 */ 3556 value = calloc(dev->blocklen - 64, sizeof(char)); 3557 SPDK_CU_ASSERT_FATAL(value != NULL); 3558 memset(value, i, dev->blocklen / 2); 3559 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 3560 CU_ASSERT(rc == 0); 3561 free(value); 3562 } 3563 3564 /* Resize the blobs, alternating 1 cluster at a time. 3565 * This thwarts run length encoding and will cause spill 3566 * over of the extents. 3567 */ 3568 for (i = 0; i < 6; i++) { 3569 spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL); 3570 poll_threads(); 3571 CU_ASSERT(g_bserrno == 0); 3572 } 3573 3574 for (i = 0; i < 2; i++) { 3575 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 3576 poll_threads(); 3577 CU_ASSERT(g_bserrno == 0); 3578 } 3579 3580 /* Close the blobs */ 3581 for (i = 0; i < 2; i++) { 3582 spdk_blob_close(blob[i], blob_op_complete, NULL); 3583 poll_threads(); 3584 CU_ASSERT(g_bserrno == 0); 3585 } 3586 3587 /* Unload the blobstore */ 3588 spdk_bs_unload(bs, bs_op_complete, NULL); 3589 poll_threads(); 3590 CU_ASSERT(g_bserrno == 0); 3591 g_bs = NULL; 3592 g_blob = NULL; 3593 g_blobid = 0; 3594 bs = NULL; 3595 3596 dev = init_dev(); 3597 /* Load an existing blob store */ 3598 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3599 poll_threads(); 3600 CU_ASSERT(g_bserrno == 0); 3601 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3602 bs = g_bs; 3603 3604 for (i = 0; i < 2; i++) { 3605 blob[i] = NULL; 3606 3607 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 3608 poll_threads(); 3609 CU_ASSERT(g_bserrno == 0); 3610 CU_ASSERT(g_blob != NULL); 3611 blob[i] = g_blob; 3612 3613 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 3614 3615 spdk_blob_close(blob[i], blob_op_complete, NULL); 3616 poll_threads(); 3617 CU_ASSERT(g_bserrno == 0); 3618 } 3619 3620 spdk_bs_unload(bs, bs_op_complete, NULL); 3621 poll_threads(); 3622 CU_ASSERT(g_bserrno == 0); 3623 g_bs = NULL; 3624 } 3625 3626 static void 3627 blob_crc(void) 3628 { 3629 struct spdk_blob_store *bs; 3630 struct spdk_bs_dev *dev; 3631 struct spdk_blob *blob; 3632 spdk_blob_id blobid; 3633 uint32_t page_num; 3634 int index; 3635 struct spdk_blob_md_page *page; 3636 struct spdk_blob_opts blob_opts; 3637 3638 dev = init_dev(); 3639 3640 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3641 poll_threads(); 3642 CU_ASSERT(g_bserrno == 0); 3643 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3644 bs = g_bs; 3645 3646 ut_spdk_blob_opts_init(&blob_opts); 3647 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3648 poll_threads(); 3649 CU_ASSERT(g_bserrno == 0); 3650 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3651 blobid = g_blobid; 3652 3653 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3654 poll_threads(); 3655 CU_ASSERT(g_bserrno == 0); 3656 CU_ASSERT(g_blob != NULL); 3657 blob = g_blob; 3658 3659 spdk_blob_close(blob, blob_op_complete, NULL); 3660 poll_threads(); 3661 CU_ASSERT(g_bserrno == 0); 3662 3663 page_num = _spdk_bs_blobid_to_page(blobid); 3664 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 3665 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3666 page->crc = 0; 3667 3668 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3669 poll_threads(); 3670 CU_ASSERT(g_bserrno == -EINVAL); 3671 CU_ASSERT(g_blob == NULL); 3672 g_bserrno = 0; 3673 3674 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3675 poll_threads(); 3676 CU_ASSERT(g_bserrno == -EINVAL); 3677 3678 spdk_bs_unload(bs, bs_op_complete, NULL); 3679 poll_threads(); 3680 CU_ASSERT(g_bserrno == 0); 3681 g_bs = NULL; 3682 } 3683 3684 static void 3685 super_block_crc(void) 3686 { 3687 struct spdk_blob_store *bs; 3688 struct spdk_bs_dev *dev; 3689 struct spdk_bs_super_block *super_block; 3690 struct spdk_bs_opts opts; 3691 3692 dev = init_dev(); 3693 spdk_bs_opts_init(&opts); 3694 3695 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3696 poll_threads(); 3697 CU_ASSERT(g_bserrno == 0); 3698 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3699 bs = g_bs; 3700 3701 spdk_bs_unload(bs, bs_op_complete, NULL); 3702 poll_threads(); 3703 CU_ASSERT(g_bserrno == 0); 3704 g_bs = NULL; 3705 3706 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 3707 super_block->crc = 0; 3708 dev = init_dev(); 3709 3710 /* Load an existing blob store */ 3711 g_bserrno = 0; 3712 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3713 poll_threads(); 3714 CU_ASSERT(g_bserrno == -EILSEQ); 3715 } 3716 3717 /* For blob dirty shutdown test case we do the following sub-test cases: 3718 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we 3719 * dirty shutdown and reload the blob store and verify the xattrs. 3720 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 3721 * reload the blob store and verify the clusters number. 3722 * 3 Create the second blob and then dirty shutdown, reload the blob store 3723 * and verify the second blob. 3724 * 4 Delete the second blob and then dirty shutdown, reload the blob store 3725 * and verify the second blob is invalid. 3726 * 5 Create the second blob again and also create the third blob, modify the 3727 * md of second blob which makes the md invalid, and then dirty shutdown, 3728 * reload the blob store verify the second blob, it should invalid and also 3729 * verify the third blob, it should correct. 3730 */ 3731 static void 3732 blob_dirty_shutdown(void) 3733 { 3734 int rc; 3735 int index; 3736 struct spdk_blob_store *bs; 3737 struct spdk_bs_dev *dev; 3738 spdk_blob_id blobid1, blobid2, blobid3; 3739 struct spdk_blob *blob; 3740 uint64_t length; 3741 uint64_t free_clusters; 3742 const void *value; 3743 size_t value_len; 3744 uint32_t page_num; 3745 struct spdk_blob_md_page *page; 3746 struct spdk_bs_opts opts; 3747 struct spdk_blob_opts blob_opts; 3748 3749 dev = init_dev(); 3750 spdk_bs_opts_init(&opts); 3751 /* Initialize a new blob store */ 3752 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3753 poll_threads(); 3754 CU_ASSERT(g_bserrno == 0); 3755 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3756 bs = g_bs; 3757 3758 /* Create first blob */ 3759 ut_spdk_blob_opts_init(&blob_opts); 3760 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3761 poll_threads(); 3762 CU_ASSERT(g_bserrno == 0); 3763 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3764 blobid1 = g_blobid; 3765 3766 spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL); 3767 poll_threads(); 3768 CU_ASSERT(g_bserrno == 0); 3769 CU_ASSERT(g_blob != NULL); 3770 blob = g_blob; 3771 3772 /* Set some xattrs */ 3773 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 3774 CU_ASSERT(rc == 0); 3775 3776 length = 2345; 3777 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3778 CU_ASSERT(rc == 0); 3779 3780 /* Put xattr that fits exactly single page. 3781 * This results in adding additional pages to MD. 3782 * First is flags and smaller xattr, second the large xattr, 3783 * third are just the extents. 3784 */ 3785 size_t xattr_length = 4072 - sizeof(struct spdk_blob_md_descriptor_xattr) - 3786 strlen("large_xattr"); 3787 char *xattr = calloc(xattr_length, sizeof(char)); 3788 SPDK_CU_ASSERT_FATAL(xattr != NULL); 3789 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); 3790 free(xattr); 3791 SPDK_CU_ASSERT_FATAL(rc == 0); 3792 3793 /* Resize the blob */ 3794 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3795 poll_threads(); 3796 CU_ASSERT(g_bserrno == 0); 3797 3798 /* Set the blob as the super blob */ 3799 spdk_bs_set_super(bs, blobid1, blob_op_complete, NULL); 3800 poll_threads(); 3801 CU_ASSERT(g_bserrno == 0); 3802 3803 free_clusters = spdk_bs_free_cluster_count(bs); 3804 3805 spdk_blob_close(blob, blob_op_complete, NULL); 3806 poll_threads(); 3807 CU_ASSERT(g_bserrno == 0); 3808 blob = NULL; 3809 g_blob = NULL; 3810 g_blobid = SPDK_BLOBID_INVALID; 3811 3812 /* Dirty shutdown */ 3813 _spdk_bs_free(bs); 3814 3815 /* reload blobstore */ 3816 dev = init_dev(); 3817 spdk_bs_opts_init(&opts); 3818 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3819 poll_threads(); 3820 CU_ASSERT(g_bserrno == 0); 3821 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3822 bs = g_bs; 3823 3824 /* Get the super blob */ 3825 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 3826 poll_threads(); 3827 CU_ASSERT(g_bserrno == 0); 3828 CU_ASSERT(blobid1 == g_blobid); 3829 3830 spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL); 3831 poll_threads(); 3832 CU_ASSERT(g_bserrno == 0); 3833 CU_ASSERT(g_blob != NULL); 3834 blob = g_blob; 3835 3836 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3837 3838 /* Get the xattrs */ 3839 value = NULL; 3840 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3841 CU_ASSERT(rc == 0); 3842 SPDK_CU_ASSERT_FATAL(value != NULL); 3843 CU_ASSERT(*(uint64_t *)value == length); 3844 CU_ASSERT(value_len == 8); 3845 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3846 3847 /* Resize the blob */ 3848 spdk_blob_resize(blob, 20, blob_op_complete, NULL); 3849 poll_threads(); 3850 CU_ASSERT(g_bserrno == 0); 3851 3852 free_clusters = spdk_bs_free_cluster_count(bs); 3853 3854 spdk_blob_close(blob, blob_op_complete, NULL); 3855 poll_threads(); 3856 CU_ASSERT(g_bserrno == 0); 3857 blob = NULL; 3858 g_blob = NULL; 3859 g_blobid = SPDK_BLOBID_INVALID; 3860 3861 /* Dirty shutdown */ 3862 _spdk_bs_free(bs); 3863 3864 /* reload the blobstore */ 3865 dev = init_dev(); 3866 spdk_bs_opts_init(&opts); 3867 /* Load an existing blob store */ 3868 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3869 poll_threads(); 3870 CU_ASSERT(g_bserrno == 0); 3871 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3872 bs = g_bs; 3873 3874 spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL); 3875 poll_threads(); 3876 CU_ASSERT(g_bserrno == 0); 3877 CU_ASSERT(g_blob != NULL); 3878 blob = g_blob; 3879 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 3880 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3881 3882 spdk_blob_close(blob, blob_op_complete, NULL); 3883 poll_threads(); 3884 CU_ASSERT(g_bserrno == 0); 3885 blob = NULL; 3886 g_blob = NULL; 3887 g_blobid = SPDK_BLOBID_INVALID; 3888 3889 /* Create second blob */ 3890 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3891 poll_threads(); 3892 CU_ASSERT(g_bserrno == 0); 3893 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3894 blobid2 = g_blobid; 3895 3896 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 3897 poll_threads(); 3898 CU_ASSERT(g_bserrno == 0); 3899 CU_ASSERT(g_blob != NULL); 3900 blob = g_blob; 3901 3902 /* Set some xattrs */ 3903 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3904 CU_ASSERT(rc == 0); 3905 3906 length = 5432; 3907 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3908 CU_ASSERT(rc == 0); 3909 3910 /* Resize the blob */ 3911 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3912 poll_threads(); 3913 CU_ASSERT(g_bserrno == 0); 3914 3915 free_clusters = spdk_bs_free_cluster_count(bs); 3916 3917 spdk_blob_close(blob, blob_op_complete, NULL); 3918 poll_threads(); 3919 CU_ASSERT(g_bserrno == 0); 3920 blob = NULL; 3921 g_blob = NULL; 3922 g_blobid = SPDK_BLOBID_INVALID; 3923 3924 /* Dirty shutdown */ 3925 _spdk_bs_free(bs); 3926 3927 /* reload the blobstore */ 3928 dev = init_dev(); 3929 spdk_bs_opts_init(&opts); 3930 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3931 poll_threads(); 3932 CU_ASSERT(g_bserrno == 0); 3933 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3934 bs = g_bs; 3935 3936 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 3937 poll_threads(); 3938 CU_ASSERT(g_bserrno == 0); 3939 CU_ASSERT(g_blob != NULL); 3940 blob = g_blob; 3941 3942 /* Get the xattrs */ 3943 value = NULL; 3944 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3945 CU_ASSERT(rc == 0); 3946 SPDK_CU_ASSERT_FATAL(value != NULL); 3947 CU_ASSERT(*(uint64_t *)value == length); 3948 CU_ASSERT(value_len == 8); 3949 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3950 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3951 3952 spdk_blob_close(blob, blob_op_complete, NULL); 3953 poll_threads(); 3954 CU_ASSERT(g_bserrno == 0); 3955 spdk_bs_delete_blob(bs, blobid2, blob_op_complete, NULL); 3956 poll_threads(); 3957 CU_ASSERT(g_bserrno == 0); 3958 3959 free_clusters = spdk_bs_free_cluster_count(bs); 3960 3961 /* Dirty shutdown */ 3962 _spdk_bs_free(bs); 3963 /* reload the blobstore */ 3964 dev = init_dev(); 3965 spdk_bs_opts_init(&opts); 3966 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3967 poll_threads(); 3968 CU_ASSERT(g_bserrno == 0); 3969 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3970 bs = g_bs; 3971 3972 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 3973 poll_threads(); 3974 CU_ASSERT(g_bserrno != 0); 3975 CU_ASSERT(g_blob == NULL); 3976 3977 spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL); 3978 poll_threads(); 3979 CU_ASSERT(g_bserrno == 0); 3980 CU_ASSERT(g_blob != NULL); 3981 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3982 spdk_blob_close(g_blob, blob_op_complete, NULL); 3983 poll_threads(); 3984 CU_ASSERT(g_bserrno == 0); 3985 3986 spdk_bs_unload(bs, bs_op_complete, NULL); 3987 poll_threads(); 3988 CU_ASSERT(g_bserrno == 0); 3989 g_bs = NULL; 3990 3991 /* reload the blobstore */ 3992 dev = init_dev(); 3993 spdk_bs_opts_init(&opts); 3994 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3995 poll_threads(); 3996 CU_ASSERT(g_bserrno == 0); 3997 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3998 bs = g_bs; 3999 4000 /* Create second blob */ 4001 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 4002 poll_threads(); 4003 CU_ASSERT(g_bserrno == 0); 4004 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4005 blobid2 = g_blobid; 4006 4007 /* Create third blob */ 4008 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 4009 poll_threads(); 4010 CU_ASSERT(g_bserrno == 0); 4011 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4012 blobid3 = g_blobid; 4013 4014 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 4015 poll_threads(); 4016 CU_ASSERT(g_bserrno == 0); 4017 CU_ASSERT(g_blob != NULL); 4018 blob = g_blob; 4019 4020 /* Set some xattrs for second blob */ 4021 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 4022 CU_ASSERT(rc == 0); 4023 4024 length = 5432; 4025 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 4026 CU_ASSERT(rc == 0); 4027 4028 spdk_blob_close(blob, blob_op_complete, NULL); 4029 poll_threads(); 4030 CU_ASSERT(g_bserrno == 0); 4031 blob = NULL; 4032 g_blob = NULL; 4033 g_blobid = SPDK_BLOBID_INVALID; 4034 4035 spdk_bs_open_blob(bs, blobid3, blob_op_with_handle_complete, NULL); 4036 poll_threads(); 4037 CU_ASSERT(g_bserrno == 0); 4038 CU_ASSERT(g_blob != NULL); 4039 blob = g_blob; 4040 4041 /* Set some xattrs for third blob */ 4042 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 4043 CU_ASSERT(rc == 0); 4044 4045 length = 5432; 4046 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 4047 CU_ASSERT(rc == 0); 4048 4049 spdk_blob_close(blob, blob_op_complete, NULL); 4050 poll_threads(); 4051 CU_ASSERT(g_bserrno == 0); 4052 blob = NULL; 4053 g_blob = NULL; 4054 g_blobid = SPDK_BLOBID_INVALID; 4055 4056 /* Mark second blob as invalid */ 4057 page_num = _spdk_bs_blobid_to_page(blobid2); 4058 4059 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 4060 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 4061 page->sequence_num = 1; 4062 page->crc = _spdk_blob_md_page_calc_crc(page); 4063 4064 free_clusters = spdk_bs_free_cluster_count(bs); 4065 4066 /* Dirty shutdown */ 4067 _spdk_bs_free(bs); 4068 /* reload the blobstore */ 4069 dev = init_dev(); 4070 spdk_bs_opts_init(&opts); 4071 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4072 poll_threads(); 4073 CU_ASSERT(g_bserrno == 0); 4074 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4075 bs = g_bs; 4076 4077 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 4078 poll_threads(); 4079 CU_ASSERT(g_bserrno != 0); 4080 CU_ASSERT(g_blob == NULL); 4081 4082 spdk_bs_open_blob(bs, blobid3, blob_op_with_handle_complete, NULL); 4083 poll_threads(); 4084 CU_ASSERT(g_bserrno == 0); 4085 CU_ASSERT(g_blob != NULL); 4086 blob = g_blob; 4087 4088 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4089 4090 spdk_blob_close(blob, blob_op_complete, NULL); 4091 poll_threads(); 4092 CU_ASSERT(g_bserrno == 0); 4093 blob = NULL; 4094 g_blob = NULL; 4095 g_blobid = SPDK_BLOBID_INVALID; 4096 4097 spdk_bs_unload(bs, bs_op_complete, NULL); 4098 poll_threads(); 4099 CU_ASSERT(g_bserrno == 0); 4100 g_bs = NULL; 4101 } 4102 4103 static void 4104 blob_flags(void) 4105 { 4106 struct spdk_blob_store *bs; 4107 struct spdk_bs_dev *dev; 4108 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 4109 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 4110 struct spdk_bs_opts opts; 4111 struct spdk_blob_opts blob_opts; 4112 int rc; 4113 4114 dev = init_dev(); 4115 spdk_bs_opts_init(&opts); 4116 ut_spdk_blob_opts_init(&blob_opts); 4117 4118 /* Initialize a new blob store */ 4119 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 4120 poll_threads(); 4121 CU_ASSERT(g_bserrno == 0); 4122 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4123 bs = g_bs; 4124 4125 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 4126 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 4127 poll_threads(); 4128 CU_ASSERT(g_bserrno == 0); 4129 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4130 blobid_invalid = g_blobid; 4131 4132 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 4133 poll_threads(); 4134 CU_ASSERT(g_bserrno == 0); 4135 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4136 blobid_data_ro = g_blobid; 4137 4138 blob_opts.clear_method = BLOB_CLEAR_WITH_WRITE_ZEROES; 4139 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 4140 poll_threads(); 4141 CU_ASSERT(g_bserrno == 0); 4142 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4143 blobid_md_ro = g_blobid; 4144 4145 spdk_bs_open_blob(bs, blobid_invalid, blob_op_with_handle_complete, NULL); 4146 poll_threads(); 4147 CU_ASSERT(g_bserrno == 0); 4148 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4149 blob_invalid = g_blob; 4150 4151 spdk_bs_open_blob(bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 4152 poll_threads(); 4153 CU_ASSERT(g_bserrno == 0); 4154 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4155 blob_data_ro = g_blob; 4156 4157 spdk_bs_open_blob(bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 4158 poll_threads(); 4159 CU_ASSERT(g_bserrno == 0); 4160 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4161 blob_md_ro = g_blob; 4162 CU_ASSERT((blob_md_ro->md_ro_flags & SPDK_BLOB_MD_RO_FLAGS_MASK) == BLOB_CLEAR_WITH_WRITE_ZEROES); 4163 4164 /* Change the size of blob_data_ro to check if flags are serialized 4165 * when blob has non zero number of extents */ 4166 spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL); 4167 poll_threads(); 4168 CU_ASSERT(g_bserrno == 0); 4169 4170 /* Set the xattr to check if flags are serialized 4171 * when blob has non zero number of xattrs */ 4172 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 4173 CU_ASSERT(rc == 0); 4174 4175 blob_invalid->invalid_flags = (1ULL << 63); 4176 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 4177 blob_data_ro->data_ro_flags = (1ULL << 62); 4178 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 4179 blob_md_ro->md_ro_flags = (1ULL << 61); 4180 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 4181 4182 g_bserrno = -1; 4183 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 4184 poll_threads(); 4185 CU_ASSERT(g_bserrno == 0); 4186 g_bserrno = -1; 4187 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 4188 poll_threads(); 4189 CU_ASSERT(g_bserrno == 0); 4190 g_bserrno = -1; 4191 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 4192 poll_threads(); 4193 CU_ASSERT(g_bserrno == 0); 4194 4195 g_bserrno = -1; 4196 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 4197 poll_threads(); 4198 CU_ASSERT(g_bserrno == 0); 4199 blob_invalid = NULL; 4200 g_bserrno = -1; 4201 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 4202 poll_threads(); 4203 CU_ASSERT(g_bserrno == 0); 4204 blob_data_ro = NULL; 4205 g_bserrno = -1; 4206 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 4207 poll_threads(); 4208 CU_ASSERT(g_bserrno == 0); 4209 blob_md_ro = NULL; 4210 4211 g_blob = NULL; 4212 g_blobid = SPDK_BLOBID_INVALID; 4213 4214 /* Unload the blob store */ 4215 spdk_bs_unload(bs, bs_op_complete, NULL); 4216 poll_threads(); 4217 CU_ASSERT(g_bserrno == 0); 4218 g_bs = NULL; 4219 4220 /* Load an existing blob store */ 4221 dev = init_dev(); 4222 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4223 poll_threads(); 4224 CU_ASSERT(g_bserrno == 0); 4225 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4226 bs = g_bs; 4227 4228 g_blob = NULL; 4229 g_bserrno = 0; 4230 spdk_bs_open_blob(bs, blobid_invalid, blob_op_with_handle_complete, NULL); 4231 poll_threads(); 4232 CU_ASSERT(g_bserrno != 0); 4233 CU_ASSERT(g_blob == NULL); 4234 4235 g_blob = NULL; 4236 g_bserrno = -1; 4237 spdk_bs_open_blob(bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 4238 poll_threads(); 4239 CU_ASSERT(g_bserrno == 0); 4240 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4241 blob_data_ro = g_blob; 4242 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 4243 CU_ASSERT(blob_data_ro->data_ro == true); 4244 CU_ASSERT(blob_data_ro->md_ro == true); 4245 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 4246 4247 g_blob = NULL; 4248 g_bserrno = -1; 4249 spdk_bs_open_blob(bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 4250 poll_threads(); 4251 CU_ASSERT(g_bserrno == 0); 4252 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4253 blob_md_ro = g_blob; 4254 CU_ASSERT(blob_md_ro->data_ro == false); 4255 CU_ASSERT(blob_md_ro->md_ro == true); 4256 4257 g_bserrno = -1; 4258 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 4259 poll_threads(); 4260 CU_ASSERT(g_bserrno == 0); 4261 4262 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 4263 poll_threads(); 4264 CU_ASSERT(g_bserrno == 0); 4265 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 4266 poll_threads(); 4267 CU_ASSERT(g_bserrno == 0); 4268 4269 spdk_bs_unload(bs, bs_op_complete, NULL); 4270 poll_threads(); 4271 CU_ASSERT(g_bserrno == 0); 4272 } 4273 4274 static void 4275 bs_version(void) 4276 { 4277 struct spdk_bs_super_block *super; 4278 struct spdk_blob_store *bs; 4279 struct spdk_bs_dev *dev; 4280 struct spdk_bs_opts opts; 4281 struct spdk_blob_opts blob_opts; 4282 spdk_blob_id blobid; 4283 4284 dev = init_dev(); 4285 spdk_bs_opts_init(&opts); 4286 4287 /* Initialize a new blob store */ 4288 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 4289 poll_threads(); 4290 CU_ASSERT(g_bserrno == 0); 4291 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4292 bs = g_bs; 4293 4294 /* Unload the blob store */ 4295 spdk_bs_unload(bs, bs_op_complete, NULL); 4296 poll_threads(); 4297 CU_ASSERT(g_bserrno == 0); 4298 g_bs = NULL; 4299 4300 /* 4301 * Change the bs version on disk. This will allow us to 4302 * test that the version does not get modified automatically 4303 * when loading and unloading the blobstore. 4304 */ 4305 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 4306 CU_ASSERT(super->version == SPDK_BS_VERSION); 4307 CU_ASSERT(super->clean == 1); 4308 super->version = 2; 4309 /* 4310 * Version 2 metadata does not have a used blobid mask, so clear 4311 * those fields in the super block and zero the corresponding 4312 * region on "disk". We will use this to ensure blob IDs are 4313 * correctly reconstructed. 4314 */ 4315 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 4316 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 4317 super->used_blobid_mask_start = 0; 4318 super->used_blobid_mask_len = 0; 4319 super->crc = _spdk_blob_md_page_calc_crc(super); 4320 4321 /* Load an existing blob store */ 4322 dev = init_dev(); 4323 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4324 poll_threads(); 4325 CU_ASSERT(g_bserrno == 0); 4326 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4327 CU_ASSERT(super->clean == 1); 4328 bs = g_bs; 4329 4330 /* 4331 * Create a blob - just to make sure that when we unload it 4332 * results in writing the super block (since metadata pages 4333 * were allocated. 4334 */ 4335 ut_spdk_blob_opts_init(&blob_opts); 4336 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 4337 poll_threads(); 4338 CU_ASSERT(g_bserrno == 0); 4339 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4340 blobid = g_blobid; 4341 4342 /* Unload the blob store */ 4343 spdk_bs_unload(bs, bs_op_complete, NULL); 4344 poll_threads(); 4345 CU_ASSERT(g_bserrno == 0); 4346 g_bs = NULL; 4347 CU_ASSERT(super->version == 2); 4348 CU_ASSERT(super->used_blobid_mask_start == 0); 4349 CU_ASSERT(super->used_blobid_mask_len == 0); 4350 4351 dev = init_dev(); 4352 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4353 poll_threads(); 4354 CU_ASSERT(g_bserrno == 0); 4355 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4356 bs = g_bs; 4357 4358 g_blob = NULL; 4359 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4360 poll_threads(); 4361 CU_ASSERT(g_bserrno == 0); 4362 CU_ASSERT(g_blob != NULL); 4363 4364 spdk_blob_close(g_blob, blob_op_complete, NULL); 4365 poll_threads(); 4366 CU_ASSERT(g_bserrno == 0); 4367 4368 spdk_bs_unload(bs, bs_op_complete, NULL); 4369 poll_threads(); 4370 CU_ASSERT(g_bserrno == 0); 4371 g_bs = NULL; 4372 CU_ASSERT(super->version == 2); 4373 CU_ASSERT(super->used_blobid_mask_start == 0); 4374 CU_ASSERT(super->used_blobid_mask_len == 0); 4375 } 4376 4377 static void 4378 blob_set_xattrs(void) 4379 { 4380 struct spdk_blob_store *bs; 4381 struct spdk_bs_dev *dev; 4382 struct spdk_blob *blob; 4383 struct spdk_blob_opts opts; 4384 spdk_blob_id blobid; 4385 const void *value; 4386 size_t value_len; 4387 char *xattr; 4388 size_t xattr_length; 4389 int rc; 4390 4391 dev = init_dev(); 4392 4393 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4394 poll_threads(); 4395 CU_ASSERT(g_bserrno == 0); 4396 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4397 bs = g_bs; 4398 4399 /* Create blob with extra attributes */ 4400 ut_spdk_blob_opts_init(&opts); 4401 4402 opts.xattrs.names = g_xattr_names; 4403 opts.xattrs.get_value = _get_xattr_value; 4404 opts.xattrs.count = 3; 4405 opts.xattrs.ctx = &g_ctx; 4406 4407 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4408 poll_threads(); 4409 CU_ASSERT(g_bserrno == 0); 4410 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4411 blobid = g_blobid; 4412 4413 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4414 poll_threads(); 4415 CU_ASSERT(g_bserrno == 0); 4416 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4417 blob = g_blob; 4418 4419 /* Get the xattrs */ 4420 value = NULL; 4421 4422 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 4423 CU_ASSERT(rc == 0); 4424 SPDK_CU_ASSERT_FATAL(value != NULL); 4425 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 4426 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 4427 4428 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 4429 CU_ASSERT(rc == 0); 4430 SPDK_CU_ASSERT_FATAL(value != NULL); 4431 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 4432 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 4433 4434 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 4435 CU_ASSERT(rc == 0); 4436 SPDK_CU_ASSERT_FATAL(value != NULL); 4437 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 4438 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 4439 4440 /* Try to get non existing attribute */ 4441 4442 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 4443 CU_ASSERT(rc == -ENOENT); 4444 4445 /* Try xattr exceeding maximum length of descriptor in single page */ 4446 xattr_length = SPDK_BS_MAX_DESC_SIZE - sizeof(struct spdk_blob_md_descriptor_xattr) - 4447 strlen("large_xattr") + 1; 4448 xattr = calloc(xattr_length, sizeof(char)); 4449 SPDK_CU_ASSERT_FATAL(xattr != NULL); 4450 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); 4451 free(xattr); 4452 SPDK_CU_ASSERT_FATAL(rc == -ENOMEM); 4453 4454 spdk_blob_close(blob, blob_op_complete, NULL); 4455 poll_threads(); 4456 CU_ASSERT(g_bserrno == 0); 4457 blob = NULL; 4458 g_blob = NULL; 4459 g_blobid = SPDK_BLOBID_INVALID; 4460 4461 /* NULL callback */ 4462 ut_spdk_blob_opts_init(&opts); 4463 opts.xattrs.names = g_xattr_names; 4464 opts.xattrs.get_value = NULL; 4465 opts.xattrs.count = 1; 4466 opts.xattrs.ctx = &g_ctx; 4467 4468 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4469 poll_threads(); 4470 CU_ASSERT(g_bserrno == -EINVAL); 4471 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4472 4473 /* NULL values */ 4474 ut_spdk_blob_opts_init(&opts); 4475 opts.xattrs.names = g_xattr_names; 4476 opts.xattrs.get_value = _get_xattr_value_null; 4477 opts.xattrs.count = 1; 4478 opts.xattrs.ctx = NULL; 4479 4480 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4481 poll_threads(); 4482 CU_ASSERT(g_bserrno == -EINVAL); 4483 4484 spdk_bs_unload(bs, bs_op_complete, NULL); 4485 poll_threads(); 4486 CU_ASSERT(g_bserrno == 0); 4487 g_bs = NULL; 4488 4489 } 4490 4491 static void 4492 blob_thin_prov_alloc(void) 4493 { 4494 struct spdk_blob_store *bs; 4495 struct spdk_bs_dev *dev; 4496 struct spdk_blob *blob; 4497 struct spdk_blob_opts opts; 4498 spdk_blob_id blobid; 4499 uint64_t free_clusters; 4500 4501 dev = init_dev(); 4502 4503 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4504 poll_threads(); 4505 CU_ASSERT(g_bserrno == 0); 4506 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4507 bs = g_bs; 4508 free_clusters = spdk_bs_free_cluster_count(bs); 4509 4510 /* Set blob as thin provisioned */ 4511 ut_spdk_blob_opts_init(&opts); 4512 opts.thin_provision = true; 4513 4514 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4515 poll_threads(); 4516 CU_ASSERT(g_bserrno == 0); 4517 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4518 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4519 blobid = g_blobid; 4520 4521 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4522 poll_threads(); 4523 CU_ASSERT(g_bserrno == 0); 4524 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4525 blob = g_blob; 4526 4527 CU_ASSERT(blob->active.num_clusters == 0); 4528 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 4529 4530 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4531 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4532 poll_threads(); 4533 CU_ASSERT(g_bserrno == 0); 4534 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4535 CU_ASSERT(blob->active.num_clusters == 5); 4536 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4537 4538 /* Grow it to 1TB - still unallocated */ 4539 spdk_blob_resize(blob, 262144, blob_op_complete, NULL); 4540 poll_threads(); 4541 CU_ASSERT(g_bserrno == 0); 4542 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4543 CU_ASSERT(blob->active.num_clusters == 262144); 4544 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 4545 4546 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4547 poll_threads(); 4548 CU_ASSERT(g_bserrno == 0); 4549 /* Sync must not change anything */ 4550 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4551 CU_ASSERT(blob->active.num_clusters == 262144); 4552 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 4553 /* Since clusters are not allocated, 4554 * number of metadata pages is expected to be minimal. 4555 */ 4556 CU_ASSERT(blob->active.num_pages == 1); 4557 4558 /* Shrink the blob to 3 clusters - still unallocated */ 4559 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 4560 poll_threads(); 4561 CU_ASSERT(g_bserrno == 0); 4562 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4563 CU_ASSERT(blob->active.num_clusters == 3); 4564 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 4565 4566 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4567 poll_threads(); 4568 CU_ASSERT(g_bserrno == 0); 4569 /* Sync must not change anything */ 4570 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4571 CU_ASSERT(blob->active.num_clusters == 3); 4572 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 4573 4574 spdk_blob_close(blob, blob_op_complete, NULL); 4575 poll_threads(); 4576 CU_ASSERT(g_bserrno == 0); 4577 4578 /* Unload the blob store */ 4579 spdk_bs_unload(bs, bs_op_complete, NULL); 4580 poll_threads(); 4581 CU_ASSERT(g_bserrno == 0); 4582 g_bs = NULL; 4583 g_blob = NULL; 4584 g_blobid = 0; 4585 4586 /* Load an existing blob store */ 4587 dev = init_dev(); 4588 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4589 poll_threads(); 4590 CU_ASSERT(g_bserrno == 0); 4591 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4592 4593 bs = g_bs; 4594 4595 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4596 poll_threads(); 4597 CU_ASSERT(g_bserrno == 0); 4598 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4599 blob = g_blob; 4600 4601 /* Check that clusters allocation and size is still the same */ 4602 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4603 CU_ASSERT(blob->active.num_clusters == 3); 4604 4605 spdk_blob_close(blob, blob_op_complete, NULL); 4606 poll_threads(); 4607 CU_ASSERT(g_bserrno == 0); 4608 4609 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4610 poll_threads(); 4611 CU_ASSERT(g_bserrno == 0); 4612 4613 spdk_bs_unload(bs, bs_op_complete, NULL); 4614 poll_threads(); 4615 CU_ASSERT(g_bserrno == 0); 4616 g_bs = NULL; 4617 } 4618 4619 static void 4620 blob_insert_cluster_msg(void) 4621 { 4622 struct spdk_blob_store *bs; 4623 struct spdk_bs_dev *dev; 4624 struct spdk_blob *blob; 4625 struct spdk_blob_opts opts; 4626 spdk_blob_id blobid; 4627 uint64_t free_clusters; 4628 uint64_t new_cluster = 0; 4629 uint32_t cluster_num = 3; 4630 uint32_t extent_page = 0; 4631 4632 dev = init_dev(); 4633 4634 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4635 poll_threads(); 4636 CU_ASSERT(g_bserrno == 0); 4637 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4638 bs = g_bs; 4639 free_clusters = spdk_bs_free_cluster_count(bs); 4640 4641 /* Set blob as thin provisioned */ 4642 ut_spdk_blob_opts_init(&opts); 4643 opts.thin_provision = true; 4644 opts.num_clusters = 4; 4645 4646 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4647 poll_threads(); 4648 CU_ASSERT(g_bserrno == 0); 4649 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4650 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4651 blobid = g_blobid; 4652 4653 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4654 poll_threads(); 4655 CU_ASSERT(g_bserrno == 0); 4656 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4657 blob = g_blob; 4658 4659 CU_ASSERT(blob->active.num_clusters == 4); 4660 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 4661 CU_ASSERT(blob->active.clusters[cluster_num] == 0); 4662 4663 /* Specify cluster_num to allocate and new_cluster will be returned to insert on md_thread. 4664 * This is to simulate behaviour when cluster is allocated after blob creation. 4665 * Such as _spdk_bs_allocate_and_copy_cluster(). */ 4666 _spdk_bs_allocate_cluster(blob, cluster_num, &new_cluster, &extent_page, false); 4667 CU_ASSERT(blob->active.clusters[cluster_num] == 0); 4668 4669 _spdk_blob_insert_cluster_on_md_thread(blob, cluster_num, new_cluster, extent_page, 4670 blob_op_complete, NULL); 4671 poll_threads(); 4672 4673 CU_ASSERT(blob->active.clusters[cluster_num] != 0); 4674 4675 spdk_blob_close(blob, blob_op_complete, NULL); 4676 poll_threads(); 4677 CU_ASSERT(g_bserrno == 0); 4678 4679 /* Unload the blob store */ 4680 spdk_bs_unload(bs, bs_op_complete, NULL); 4681 poll_threads(); 4682 CU_ASSERT(g_bserrno == 0); 4683 g_bs = NULL; 4684 g_blob = NULL; 4685 g_blobid = 0; 4686 4687 /* Load an existing blob store */ 4688 dev = init_dev(); 4689 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4690 poll_threads(); 4691 CU_ASSERT(g_bserrno == 0); 4692 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4693 4694 bs = g_bs; 4695 4696 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4697 poll_threads(); 4698 CU_ASSERT(g_bserrno == 0); 4699 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4700 blob = g_blob; 4701 4702 CU_ASSERT(blob->active.clusters[cluster_num] != 0); 4703 4704 spdk_blob_close(blob, blob_op_complete, NULL); 4705 poll_threads(); 4706 CU_ASSERT(g_bserrno == 0); 4707 4708 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4709 poll_threads(); 4710 CU_ASSERT(g_bserrno == 0); 4711 4712 spdk_bs_unload(bs, bs_op_complete, NULL); 4713 poll_threads(); 4714 CU_ASSERT(g_bserrno == 0); 4715 g_bs = NULL; 4716 } 4717 4718 static void 4719 blob_thin_prov_rw(void) 4720 { 4721 static const uint8_t zero[10 * 4096] = { 0 }; 4722 struct spdk_blob_store *bs; 4723 struct spdk_bs_dev *dev; 4724 struct spdk_blob *blob; 4725 struct spdk_io_channel *channel, *channel_thread1; 4726 struct spdk_blob_opts opts; 4727 spdk_blob_id blobid; 4728 uint64_t free_clusters; 4729 uint64_t page_size; 4730 uint8_t payload_read[10 * 4096]; 4731 uint8_t payload_write[10 * 4096]; 4732 uint64_t write_bytes; 4733 uint64_t read_bytes; 4734 4735 dev = init_dev(); 4736 4737 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4738 poll_threads(); 4739 CU_ASSERT(g_bserrno == 0); 4740 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4741 bs = g_bs; 4742 free_clusters = spdk_bs_free_cluster_count(bs); 4743 page_size = spdk_bs_get_page_size(bs); 4744 4745 channel = spdk_bs_alloc_io_channel(bs); 4746 CU_ASSERT(channel != NULL); 4747 4748 ut_spdk_blob_opts_init(&opts); 4749 opts.thin_provision = true; 4750 4751 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4752 poll_threads(); 4753 CU_ASSERT(g_bserrno == 0); 4754 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4755 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4756 blobid = g_blobid; 4757 4758 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4759 poll_threads(); 4760 CU_ASSERT(g_bserrno == 0); 4761 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4762 blob = g_blob; 4763 4764 CU_ASSERT(blob->active.num_clusters == 0); 4765 4766 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4767 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4768 poll_threads(); 4769 CU_ASSERT(g_bserrno == 0); 4770 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4771 CU_ASSERT(blob->active.num_clusters == 5); 4772 4773 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4774 poll_threads(); 4775 CU_ASSERT(g_bserrno == 0); 4776 /* Sync must not change anything */ 4777 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4778 CU_ASSERT(blob->active.num_clusters == 5); 4779 4780 /* Payload should be all zeros from unallocated clusters */ 4781 memset(payload_read, 0xFF, sizeof(payload_read)); 4782 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4783 poll_threads(); 4784 CU_ASSERT(g_bserrno == 0); 4785 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4786 4787 write_bytes = g_dev_write_bytes; 4788 read_bytes = g_dev_read_bytes; 4789 4790 /* Perform write on thread 1. That will allocate cluster on thread 0 via send_msg */ 4791 set_thread(1); 4792 channel_thread1 = spdk_bs_alloc_io_channel(bs); 4793 CU_ASSERT(channel_thread1 != NULL); 4794 memset(payload_write, 0xE5, sizeof(payload_write)); 4795 spdk_blob_io_write(blob, channel_thread1, payload_write, 4, 10, blob_op_complete, NULL); 4796 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4797 /* Perform write on thread 0. That will try to allocate cluster, 4798 * but fail due to another thread issuing the cluster allocation first. */ 4799 set_thread(0); 4800 memset(payload_write, 0xE5, sizeof(payload_write)); 4801 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4802 CU_ASSERT(free_clusters - 2 == spdk_bs_free_cluster_count(bs)); 4803 poll_threads(); 4804 CU_ASSERT(g_bserrno == 0); 4805 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4806 /* For thin-provisioned blob we need to write 20 pages plus one page metadata and 4807 * read 0 bytes */ 4808 if (g_use_extent_table) { 4809 /* Add one more page for EXTENT_PAGE write */ 4810 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 22); 4811 } else { 4812 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 21); 4813 } 4814 CU_ASSERT(g_dev_read_bytes - read_bytes == 0); 4815 4816 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4817 poll_threads(); 4818 CU_ASSERT(g_bserrno == 0); 4819 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4820 4821 spdk_blob_close(blob, blob_op_complete, NULL); 4822 poll_threads(); 4823 CU_ASSERT(g_bserrno == 0); 4824 4825 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4826 poll_threads(); 4827 CU_ASSERT(g_bserrno == 0); 4828 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4829 4830 set_thread(1); 4831 spdk_bs_free_io_channel(channel_thread1); 4832 set_thread(0); 4833 spdk_bs_free_io_channel(channel); 4834 poll_threads(); 4835 4836 /* Unload the blob store */ 4837 spdk_bs_unload(bs, bs_op_complete, NULL); 4838 poll_threads(); 4839 CU_ASSERT(g_bserrno == 0); 4840 g_bs = NULL; 4841 g_blob = NULL; 4842 g_blobid = 0; 4843 } 4844 4845 static void 4846 blob_thin_prov_rle(void) 4847 { 4848 static const uint8_t zero[10 * 4096] = { 0 }; 4849 struct spdk_blob_store *bs; 4850 struct spdk_bs_dev *dev; 4851 struct spdk_blob *blob; 4852 struct spdk_io_channel *channel; 4853 struct spdk_blob_opts opts; 4854 spdk_blob_id blobid; 4855 uint64_t free_clusters; 4856 uint64_t page_size; 4857 uint8_t payload_read[10 * 4096]; 4858 uint8_t payload_write[10 * 4096]; 4859 uint64_t write_bytes; 4860 uint64_t read_bytes; 4861 uint64_t io_unit; 4862 4863 dev = init_dev(); 4864 4865 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4866 poll_threads(); 4867 CU_ASSERT(g_bserrno == 0); 4868 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4869 bs = g_bs; 4870 free_clusters = spdk_bs_free_cluster_count(bs); 4871 page_size = spdk_bs_get_page_size(bs); 4872 4873 ut_spdk_blob_opts_init(&opts); 4874 opts.thin_provision = true; 4875 opts.num_clusters = 5; 4876 4877 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4878 poll_threads(); 4879 CU_ASSERT(g_bserrno == 0); 4880 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4881 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4882 blobid = g_blobid; 4883 4884 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4885 poll_threads(); 4886 CU_ASSERT(g_bserrno == 0); 4887 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4888 blob = g_blob; 4889 4890 channel = spdk_bs_alloc_io_channel(bs); 4891 CU_ASSERT(channel != NULL); 4892 4893 /* Target specifically second cluster in a blob as first allocation */ 4894 io_unit = _spdk_bs_cluster_to_page(bs, 1) * _spdk_bs_io_unit_per_page(bs); 4895 4896 /* Payload should be all zeros from unallocated clusters */ 4897 memset(payload_read, 0xFF, sizeof(payload_read)); 4898 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL); 4899 poll_threads(); 4900 CU_ASSERT(g_bserrno == 0); 4901 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4902 4903 write_bytes = g_dev_write_bytes; 4904 read_bytes = g_dev_read_bytes; 4905 4906 /* Issue write to second cluster in a blob */ 4907 memset(payload_write, 0xE5, sizeof(payload_write)); 4908 spdk_blob_io_write(blob, channel, payload_write, io_unit, 10, blob_op_complete, NULL); 4909 poll_threads(); 4910 CU_ASSERT(g_bserrno == 0); 4911 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4912 /* For thin-provisioned blob we need to write 10 pages plus one page metadata and 4913 * read 0 bytes */ 4914 if (g_use_extent_table) { 4915 /* Add one more page for EXTENT_PAGE write */ 4916 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 12); 4917 } else { 4918 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11); 4919 } 4920 CU_ASSERT(g_dev_read_bytes - read_bytes == 0); 4921 4922 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL); 4923 poll_threads(); 4924 CU_ASSERT(g_bserrno == 0); 4925 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4926 4927 spdk_bs_free_io_channel(channel); 4928 poll_threads(); 4929 4930 spdk_blob_close(blob, blob_op_complete, NULL); 4931 poll_threads(); 4932 CU_ASSERT(g_bserrno == 0); 4933 4934 /* Unload the blob store */ 4935 spdk_bs_unload(bs, bs_op_complete, NULL); 4936 poll_threads(); 4937 CU_ASSERT(g_bserrno == 0); 4938 g_bs = NULL; 4939 g_blob = NULL; 4940 g_blobid = 0; 4941 4942 /* Load an existing blob store */ 4943 dev = init_dev(); 4944 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4945 poll_threads(); 4946 CU_ASSERT(g_bserrno == 0); 4947 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4948 4949 bs = g_bs; 4950 4951 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4952 poll_threads(); 4953 CU_ASSERT(g_bserrno == 0); 4954 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4955 blob = g_blob; 4956 4957 channel = spdk_bs_alloc_io_channel(bs); 4958 CU_ASSERT(channel != NULL); 4959 4960 /* Read second cluster after blob reload to confirm data written */ 4961 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL); 4962 poll_threads(); 4963 CU_ASSERT(g_bserrno == 0); 4964 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4965 4966 spdk_bs_free_io_channel(channel); 4967 poll_threads(); 4968 4969 spdk_blob_close(blob, blob_op_complete, NULL); 4970 poll_threads(); 4971 CU_ASSERT(g_bserrno == 0); 4972 4973 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4974 poll_threads(); 4975 CU_ASSERT(g_bserrno == 0); 4976 4977 spdk_bs_unload(bs, bs_op_complete, NULL); 4978 poll_threads(); 4979 CU_ASSERT(g_bserrno == 0); 4980 g_bs = NULL; 4981 } 4982 4983 static void 4984 blob_thin_prov_rw_iov(void) 4985 { 4986 static const uint8_t zero[10 * 4096] = { 0 }; 4987 struct spdk_blob_store *bs; 4988 struct spdk_bs_dev *dev; 4989 struct spdk_blob *blob; 4990 struct spdk_io_channel *channel; 4991 struct spdk_blob_opts opts; 4992 spdk_blob_id blobid; 4993 uint64_t free_clusters; 4994 uint8_t payload_read[10 * 4096]; 4995 uint8_t payload_write[10 * 4096]; 4996 struct iovec iov_read[3]; 4997 struct iovec iov_write[3]; 4998 4999 dev = init_dev(); 5000 5001 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5002 poll_threads(); 5003 CU_ASSERT(g_bserrno == 0); 5004 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5005 bs = g_bs; 5006 free_clusters = spdk_bs_free_cluster_count(bs); 5007 5008 channel = spdk_bs_alloc_io_channel(bs); 5009 CU_ASSERT(channel != NULL); 5010 5011 ut_spdk_blob_opts_init(&opts); 5012 opts.thin_provision = true; 5013 5014 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5015 poll_threads(); 5016 CU_ASSERT(g_bserrno == 0); 5017 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5018 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5019 blobid = g_blobid; 5020 5021 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5022 poll_threads(); 5023 CU_ASSERT(g_bserrno == 0); 5024 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5025 blob = g_blob; 5026 5027 CU_ASSERT(blob->active.num_clusters == 0); 5028 5029 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 5030 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 5031 poll_threads(); 5032 CU_ASSERT(g_bserrno == 0); 5033 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5034 CU_ASSERT(blob->active.num_clusters == 5); 5035 5036 spdk_blob_sync_md(blob, blob_op_complete, NULL); 5037 poll_threads(); 5038 CU_ASSERT(g_bserrno == 0); 5039 /* Sync must not change anything */ 5040 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5041 CU_ASSERT(blob->active.num_clusters == 5); 5042 5043 /* Payload should be all zeros from unallocated clusters */ 5044 memset(payload_read, 0xAA, sizeof(payload_read)); 5045 iov_read[0].iov_base = payload_read; 5046 iov_read[0].iov_len = 3 * 4096; 5047 iov_read[1].iov_base = payload_read + 3 * 4096; 5048 iov_read[1].iov_len = 4 * 4096; 5049 iov_read[2].iov_base = payload_read + 7 * 4096; 5050 iov_read[2].iov_len = 3 * 4096; 5051 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 5052 poll_threads(); 5053 CU_ASSERT(g_bserrno == 0); 5054 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 5055 5056 memset(payload_write, 0xE5, sizeof(payload_write)); 5057 iov_write[0].iov_base = payload_write; 5058 iov_write[0].iov_len = 1 * 4096; 5059 iov_write[1].iov_base = payload_write + 1 * 4096; 5060 iov_write[1].iov_len = 5 * 4096; 5061 iov_write[2].iov_base = payload_write + 6 * 4096; 5062 iov_write[2].iov_len = 4 * 4096; 5063 5064 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 5065 poll_threads(); 5066 CU_ASSERT(g_bserrno == 0); 5067 5068 memset(payload_read, 0xAA, sizeof(payload_read)); 5069 iov_read[0].iov_base = payload_read; 5070 iov_read[0].iov_len = 3 * 4096; 5071 iov_read[1].iov_base = payload_read + 3 * 4096; 5072 iov_read[1].iov_len = 4 * 4096; 5073 iov_read[2].iov_base = payload_read + 7 * 4096; 5074 iov_read[2].iov_len = 3 * 4096; 5075 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 5076 poll_threads(); 5077 CU_ASSERT(g_bserrno == 0); 5078 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 5079 5080 spdk_blob_close(blob, blob_op_complete, NULL); 5081 poll_threads(); 5082 CU_ASSERT(g_bserrno == 0); 5083 5084 spdk_bs_free_io_channel(channel); 5085 poll_threads(); 5086 5087 /* Unload the blob store */ 5088 spdk_bs_unload(bs, bs_op_complete, NULL); 5089 poll_threads(); 5090 CU_ASSERT(g_bserrno == 0); 5091 g_bs = NULL; 5092 g_blob = NULL; 5093 g_blobid = 0; 5094 } 5095 5096 struct iter_ctx { 5097 int current_iter; 5098 spdk_blob_id blobid[4]; 5099 }; 5100 5101 static void 5102 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 5103 { 5104 struct iter_ctx *iter_ctx = arg; 5105 spdk_blob_id blobid; 5106 5107 CU_ASSERT(bserrno == 0); 5108 blobid = spdk_blob_get_id(blob); 5109 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 5110 } 5111 5112 static void 5113 bs_load_iter(void) 5114 { 5115 struct spdk_blob_store *bs; 5116 struct spdk_bs_dev *dev; 5117 struct iter_ctx iter_ctx = { 0 }; 5118 struct spdk_blob *blob; 5119 int i, rc; 5120 struct spdk_bs_opts opts; 5121 struct spdk_blob_opts blob_opts; 5122 5123 dev = init_dev(); 5124 spdk_bs_opts_init(&opts); 5125 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 5126 5127 /* Initialize a new blob store */ 5128 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 5129 poll_threads(); 5130 CU_ASSERT(g_bserrno == 0); 5131 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5132 bs = g_bs; 5133 5134 ut_spdk_blob_opts_init(&blob_opts); 5135 5136 for (i = 0; i < 4; i++) { 5137 g_bserrno = -1; 5138 g_blobid = SPDK_BLOBID_INVALID; 5139 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 5140 poll_threads(); 5141 CU_ASSERT(g_bserrno == 0); 5142 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5143 iter_ctx.blobid[i] = g_blobid; 5144 5145 g_bserrno = -1; 5146 g_blob = NULL; 5147 spdk_bs_open_blob(bs, g_blobid, blob_op_with_handle_complete, NULL); 5148 poll_threads(); 5149 CU_ASSERT(g_bserrno == 0); 5150 CU_ASSERT(g_blob != NULL); 5151 blob = g_blob; 5152 5153 /* Just save the blobid as an xattr for testing purposes. */ 5154 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 5155 CU_ASSERT(rc == 0); 5156 5157 /* Resize the blob */ 5158 spdk_blob_resize(blob, i, blob_op_complete, NULL); 5159 poll_threads(); 5160 CU_ASSERT(g_bserrno == 0); 5161 5162 spdk_blob_close(blob, blob_op_complete, NULL); 5163 poll_threads(); 5164 CU_ASSERT(g_bserrno == 0); 5165 } 5166 5167 g_bserrno = -1; 5168 spdk_bs_unload(bs, bs_op_complete, NULL); 5169 poll_threads(); 5170 CU_ASSERT(g_bserrno == 0); 5171 5172 dev = init_dev(); 5173 spdk_bs_opts_init(&opts); 5174 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 5175 opts.iter_cb_fn = test_iter; 5176 opts.iter_cb_arg = &iter_ctx; 5177 5178 /* Test blob iteration during load after a clean shutdown. */ 5179 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 5180 poll_threads(); 5181 CU_ASSERT(g_bserrno == 0); 5182 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5183 bs = g_bs; 5184 5185 /* Dirty shutdown */ 5186 _spdk_bs_free(bs); 5187 5188 dev = init_dev(); 5189 spdk_bs_opts_init(&opts); 5190 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 5191 opts.iter_cb_fn = test_iter; 5192 iter_ctx.current_iter = 0; 5193 opts.iter_cb_arg = &iter_ctx; 5194 5195 /* Test blob iteration during load after a dirty shutdown. */ 5196 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 5197 poll_threads(); 5198 CU_ASSERT(g_bserrno == 0); 5199 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5200 bs = g_bs; 5201 5202 spdk_bs_unload(bs, bs_op_complete, NULL); 5203 poll_threads(); 5204 CU_ASSERT(g_bserrno == 0); 5205 g_bs = NULL; 5206 } 5207 5208 static void 5209 blob_snapshot_rw(void) 5210 { 5211 static const uint8_t zero[10 * 4096] = { 0 }; 5212 struct spdk_blob_store *bs; 5213 struct spdk_bs_dev *dev; 5214 struct spdk_blob *blob, *snapshot; 5215 struct spdk_io_channel *channel; 5216 struct spdk_blob_opts opts; 5217 spdk_blob_id blobid, snapshotid; 5218 uint64_t free_clusters; 5219 uint64_t cluster_size; 5220 uint64_t page_size; 5221 uint8_t payload_read[10 * 4096]; 5222 uint8_t payload_write[10 * 4096]; 5223 uint64_t write_bytes; 5224 uint64_t read_bytes; 5225 5226 dev = init_dev(); 5227 5228 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5229 poll_threads(); 5230 CU_ASSERT(g_bserrno == 0); 5231 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5232 bs = g_bs; 5233 free_clusters = spdk_bs_free_cluster_count(bs); 5234 cluster_size = spdk_bs_get_cluster_size(bs); 5235 page_size = spdk_bs_get_page_size(bs); 5236 5237 channel = spdk_bs_alloc_io_channel(bs); 5238 CU_ASSERT(channel != NULL); 5239 5240 ut_spdk_blob_opts_init(&opts); 5241 opts.thin_provision = true; 5242 opts.num_clusters = 5; 5243 5244 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5245 poll_threads(); 5246 CU_ASSERT(g_bserrno == 0); 5247 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5248 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5249 blobid = g_blobid; 5250 5251 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5252 poll_threads(); 5253 CU_ASSERT(g_bserrno == 0); 5254 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5255 blob = g_blob; 5256 5257 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5258 5259 memset(payload_read, 0xFF, sizeof(payload_read)); 5260 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 5261 poll_threads(); 5262 CU_ASSERT(g_bserrno == 0); 5263 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 5264 5265 memset(payload_write, 0xE5, sizeof(payload_write)); 5266 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 5267 poll_threads(); 5268 CU_ASSERT(g_bserrno == 0); 5269 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5270 5271 /* Create snapshot from blob */ 5272 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5273 poll_threads(); 5274 CU_ASSERT(g_bserrno == 0); 5275 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5276 snapshotid = g_blobid; 5277 5278 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5279 poll_threads(); 5280 CU_ASSERT(g_bserrno == 0); 5281 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5282 snapshot = g_blob; 5283 CU_ASSERT(snapshot->data_ro == true); 5284 CU_ASSERT(snapshot->md_ro == true); 5285 5286 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 5287 5288 write_bytes = g_dev_write_bytes; 5289 read_bytes = g_dev_read_bytes; 5290 5291 memset(payload_write, 0xAA, sizeof(payload_write)); 5292 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 5293 poll_threads(); 5294 CU_ASSERT(g_bserrno == 0); 5295 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5296 5297 /* For a clone we need to allocate and copy one cluster, update one page of metadata 5298 * and then write 10 pages of payload. 5299 */ 5300 if (g_use_extent_table) { 5301 /* Add one more page for EXTENT_PAGE write */ 5302 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 12 + cluster_size); 5303 } else { 5304 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11 + cluster_size); 5305 } 5306 CU_ASSERT(g_dev_read_bytes - read_bytes == cluster_size); 5307 5308 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 5309 poll_threads(); 5310 CU_ASSERT(g_bserrno == 0); 5311 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 5312 5313 /* Data on snapshot should not change after write to clone */ 5314 memset(payload_write, 0xE5, sizeof(payload_write)); 5315 spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL); 5316 poll_threads(); 5317 CU_ASSERT(g_bserrno == 0); 5318 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 5319 5320 spdk_blob_close(blob, blob_op_complete, NULL); 5321 poll_threads(); 5322 CU_ASSERT(g_bserrno == 0); 5323 5324 spdk_blob_close(snapshot, blob_op_complete, NULL); 5325 poll_threads(); 5326 CU_ASSERT(g_bserrno == 0); 5327 5328 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5329 poll_threads(); 5330 CU_ASSERT(g_bserrno == 0); 5331 5332 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5333 poll_threads(); 5334 CU_ASSERT(g_bserrno == 0); 5335 5336 spdk_bs_free_io_channel(channel); 5337 poll_threads(); 5338 5339 /* Unload the blob store */ 5340 spdk_bs_unload(bs, bs_op_complete, NULL); 5341 poll_threads(); 5342 CU_ASSERT(g_bserrno == 0); 5343 g_bs = NULL; 5344 g_blob = NULL; 5345 g_blobid = 0; 5346 } 5347 5348 static void 5349 blob_snapshot_rw_iov(void) 5350 { 5351 static const uint8_t zero[10 * 4096] = { 0 }; 5352 struct spdk_blob_store *bs; 5353 struct spdk_bs_dev *dev; 5354 struct spdk_blob *blob, *snapshot; 5355 struct spdk_io_channel *channel; 5356 struct spdk_blob_opts opts; 5357 spdk_blob_id blobid, snapshotid; 5358 uint64_t free_clusters; 5359 uint8_t payload_read[10 * 4096]; 5360 uint8_t payload_write[10 * 4096]; 5361 struct iovec iov_read[3]; 5362 struct iovec iov_write[3]; 5363 5364 dev = init_dev(); 5365 5366 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5367 poll_threads(); 5368 CU_ASSERT(g_bserrno == 0); 5369 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5370 bs = g_bs; 5371 free_clusters = spdk_bs_free_cluster_count(bs); 5372 5373 channel = spdk_bs_alloc_io_channel(bs); 5374 CU_ASSERT(channel != NULL); 5375 5376 ut_spdk_blob_opts_init(&opts); 5377 opts.thin_provision = true; 5378 opts.num_clusters = 5; 5379 5380 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5381 poll_threads(); 5382 CU_ASSERT(g_bserrno == 0); 5383 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5384 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5385 blobid = g_blobid; 5386 5387 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5388 poll_threads(); 5389 CU_ASSERT(g_bserrno == 0); 5390 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5391 blob = g_blob; 5392 5393 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5394 5395 /* Create snapshot from blob */ 5396 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5397 poll_threads(); 5398 CU_ASSERT(g_bserrno == 0); 5399 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5400 snapshotid = g_blobid; 5401 5402 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5403 poll_threads(); 5404 CU_ASSERT(g_bserrno == 0); 5405 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5406 snapshot = g_blob; 5407 CU_ASSERT(snapshot->data_ro == true); 5408 CU_ASSERT(snapshot->md_ro == true); 5409 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 5410 5411 /* Payload should be all zeros from unallocated clusters */ 5412 memset(payload_read, 0xAA, sizeof(payload_read)); 5413 iov_read[0].iov_base = payload_read; 5414 iov_read[0].iov_len = 3 * 4096; 5415 iov_read[1].iov_base = payload_read + 3 * 4096; 5416 iov_read[1].iov_len = 4 * 4096; 5417 iov_read[2].iov_base = payload_read + 7 * 4096; 5418 iov_read[2].iov_len = 3 * 4096; 5419 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 5420 poll_threads(); 5421 CU_ASSERT(g_bserrno == 0); 5422 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 5423 5424 memset(payload_write, 0xE5, sizeof(payload_write)); 5425 iov_write[0].iov_base = payload_write; 5426 iov_write[0].iov_len = 1 * 4096; 5427 iov_write[1].iov_base = payload_write + 1 * 4096; 5428 iov_write[1].iov_len = 5 * 4096; 5429 iov_write[2].iov_base = payload_write + 6 * 4096; 5430 iov_write[2].iov_len = 4 * 4096; 5431 5432 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 5433 poll_threads(); 5434 CU_ASSERT(g_bserrno == 0); 5435 5436 memset(payload_read, 0xAA, sizeof(payload_read)); 5437 iov_read[0].iov_base = payload_read; 5438 iov_read[0].iov_len = 3 * 4096; 5439 iov_read[1].iov_base = payload_read + 3 * 4096; 5440 iov_read[1].iov_len = 4 * 4096; 5441 iov_read[2].iov_base = payload_read + 7 * 4096; 5442 iov_read[2].iov_len = 3 * 4096; 5443 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 5444 poll_threads(); 5445 CU_ASSERT(g_bserrno == 0); 5446 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 5447 5448 spdk_blob_close(blob, blob_op_complete, NULL); 5449 poll_threads(); 5450 CU_ASSERT(g_bserrno == 0); 5451 5452 spdk_blob_close(snapshot, blob_op_complete, NULL); 5453 poll_threads(); 5454 CU_ASSERT(g_bserrno == 0); 5455 5456 spdk_bs_free_io_channel(channel); 5457 poll_threads(); 5458 5459 /* Unload the blob store */ 5460 spdk_bs_unload(bs, bs_op_complete, NULL); 5461 poll_threads(); 5462 CU_ASSERT(g_bserrno == 0); 5463 g_bs = NULL; 5464 g_blob = NULL; 5465 g_blobid = 0; 5466 } 5467 5468 /** 5469 * Inflate / decouple parent rw unit tests. 5470 * 5471 * -------------- 5472 * original blob: 0 1 2 3 4 5473 * ,---------+---------+---------+---------+---------. 5474 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 5475 * +---------+---------+---------+---------+---------+ 5476 * snapshot2 | - |yyyyyyyyy| - |yyyyyyyyy| - | 5477 * +---------+---------+---------+---------+---------+ 5478 * blob | - |zzzzzzzzz| - | - | - | 5479 * '---------+---------+---------+---------+---------' 5480 * . . . . . . 5481 * -------- . . . . . . 5482 * inflate: . . . . . . 5483 * ,---------+---------+---------+---------+---------. 5484 * blob |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000| 5485 * '---------+---------+---------+---------+---------' 5486 * 5487 * NOTE: needs to allocate 4 clusters, thin provisioning removed, dependency 5488 * on snapshot2 and snapshot removed . . . 5489 * . . . . . . 5490 * ---------------- . . . . . . 5491 * decouple parent: . . . . . . 5492 * ,---------+---------+---------+---------+---------. 5493 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 5494 * +---------+---------+---------+---------+---------+ 5495 * blob | - |zzzzzzzzz| - |yyyyyyyyy| - | 5496 * '---------+---------+---------+---------+---------' 5497 * 5498 * NOTE: needs to allocate 1 cluster, 3 clusters unallocated, dependency 5499 * on snapshot2 removed and on snapshot still exists. Snapshot2 5500 * should remain a clone of snapshot. 5501 */ 5502 static void 5503 _blob_inflate_rw(bool decouple_parent) 5504 { 5505 struct spdk_blob_store *bs; 5506 struct spdk_bs_dev *dev; 5507 struct spdk_blob *blob, *snapshot, *snapshot2; 5508 struct spdk_io_channel *channel; 5509 struct spdk_blob_opts opts; 5510 spdk_blob_id blobid, snapshotid, snapshot2id; 5511 uint64_t free_clusters; 5512 uint64_t cluster_size; 5513 5514 uint64_t payload_size; 5515 uint8_t *payload_read; 5516 uint8_t *payload_write; 5517 uint8_t *payload_clone; 5518 5519 uint64_t pages_per_cluster; 5520 uint64_t pages_per_payload; 5521 5522 int i; 5523 spdk_blob_id ids[2]; 5524 size_t count; 5525 5526 dev = init_dev(); 5527 5528 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5529 poll_threads(); 5530 CU_ASSERT(g_bserrno == 0); 5531 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5532 bs = g_bs; 5533 5534 free_clusters = spdk_bs_free_cluster_count(bs); 5535 cluster_size = spdk_bs_get_cluster_size(bs); 5536 pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs); 5537 pages_per_payload = pages_per_cluster * 5; 5538 5539 payload_size = cluster_size * 5; 5540 5541 payload_read = malloc(payload_size); 5542 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 5543 5544 payload_write = malloc(payload_size); 5545 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 5546 5547 payload_clone = malloc(payload_size); 5548 SPDK_CU_ASSERT_FATAL(payload_clone != NULL); 5549 5550 channel = spdk_bs_alloc_io_channel(bs); 5551 SPDK_CU_ASSERT_FATAL(channel != NULL); 5552 5553 /* Create blob */ 5554 ut_spdk_blob_opts_init(&opts); 5555 opts.thin_provision = true; 5556 opts.num_clusters = 5; 5557 5558 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5559 poll_threads(); 5560 CU_ASSERT(g_bserrno == 0); 5561 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5562 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5563 blobid = g_blobid; 5564 5565 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5566 poll_threads(); 5567 CU_ASSERT(g_bserrno == 0); 5568 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5569 blob = g_blob; 5570 5571 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5572 5573 /* 1) Initial read should return zeroed payload */ 5574 memset(payload_read, 0xFF, payload_size); 5575 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5576 blob_op_complete, NULL); 5577 poll_threads(); 5578 CU_ASSERT(g_bserrno == 0); 5579 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 5580 5581 /* Fill whole blob with a pattern, except last cluster (to be sure it 5582 * isn't allocated) */ 5583 memset(payload_write, 0xE5, payload_size - cluster_size); 5584 spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload - 5585 pages_per_cluster, blob_op_complete, NULL); 5586 poll_threads(); 5587 CU_ASSERT(g_bserrno == 0); 5588 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5589 5590 /* 2) Create snapshot from blob (first level) */ 5591 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5592 poll_threads(); 5593 CU_ASSERT(g_bserrno == 0); 5594 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5595 snapshotid = g_blobid; 5596 5597 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5598 poll_threads(); 5599 CU_ASSERT(g_bserrno == 0); 5600 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5601 snapshot = g_blob; 5602 CU_ASSERT(snapshot->data_ro == true); 5603 CU_ASSERT(snapshot->md_ro == true); 5604 5605 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 5606 5607 /* Write every second cluster with a pattern. 5608 * 5609 * Last cluster shouldn't be written, to be sure that snapshot nor clone 5610 * doesn't allocate it. 5611 * 5612 * payload_clone stores expected result on "blob" read at the time and 5613 * is used only to check data consistency on clone before and after 5614 * inflation. Initially we fill it with a backing snapshots pattern 5615 * used before. 5616 */ 5617 memset(payload_clone, 0xE5, payload_size - cluster_size); 5618 memset(payload_clone + payload_size - cluster_size, 0x00, cluster_size); 5619 memset(payload_write, 0xAA, payload_size); 5620 for (i = 1; i < 5; i += 2) { 5621 spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster, 5622 pages_per_cluster, blob_op_complete, NULL); 5623 poll_threads(); 5624 CU_ASSERT(g_bserrno == 0); 5625 5626 /* Update expected result */ 5627 memcpy(payload_clone + (cluster_size * i), payload_write, 5628 cluster_size); 5629 } 5630 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5631 5632 /* Check data consistency on clone */ 5633 memset(payload_read, 0xFF, payload_size); 5634 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5635 blob_op_complete, NULL); 5636 poll_threads(); 5637 CU_ASSERT(g_bserrno == 0); 5638 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5639 5640 /* 3) Create second levels snapshot from blob */ 5641 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5642 poll_threads(); 5643 CU_ASSERT(g_bserrno == 0); 5644 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5645 snapshot2id = g_blobid; 5646 5647 spdk_bs_open_blob(bs, snapshot2id, blob_op_with_handle_complete, NULL); 5648 poll_threads(); 5649 CU_ASSERT(g_bserrno == 0); 5650 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5651 snapshot2 = g_blob; 5652 CU_ASSERT(snapshot2->data_ro == true); 5653 CU_ASSERT(snapshot2->md_ro == true); 5654 5655 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 5); 5656 5657 CU_ASSERT(snapshot2->parent_id == snapshotid); 5658 5659 /* Write one cluster on the top level blob. This cluster (1) covers 5660 * already allocated cluster in the snapshot2, so shouldn't be inflated 5661 * at all */ 5662 spdk_blob_io_write(blob, channel, payload_write, pages_per_cluster, 5663 pages_per_cluster, blob_op_complete, NULL); 5664 poll_threads(); 5665 CU_ASSERT(g_bserrno == 0); 5666 5667 /* Update expected result */ 5668 memcpy(payload_clone + cluster_size, payload_write, cluster_size); 5669 5670 /* Check data consistency on clone */ 5671 memset(payload_read, 0xFF, payload_size); 5672 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5673 blob_op_complete, NULL); 5674 poll_threads(); 5675 CU_ASSERT(g_bserrno == 0); 5676 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5677 5678 5679 /* Close all blobs */ 5680 spdk_blob_close(blob, blob_op_complete, NULL); 5681 poll_threads(); 5682 CU_ASSERT(g_bserrno == 0); 5683 5684 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5685 poll_threads(); 5686 CU_ASSERT(g_bserrno == 0); 5687 5688 spdk_blob_close(snapshot, blob_op_complete, NULL); 5689 poll_threads(); 5690 CU_ASSERT(g_bserrno == 0); 5691 5692 /* Check snapshot-clone relations */ 5693 count = 2; 5694 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5695 CU_ASSERT(count == 1); 5696 CU_ASSERT(ids[0] == snapshot2id); 5697 5698 count = 2; 5699 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5700 CU_ASSERT(count == 1); 5701 CU_ASSERT(ids[0] == blobid); 5702 5703 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshot2id); 5704 5705 free_clusters = spdk_bs_free_cluster_count(bs); 5706 if (!decouple_parent) { 5707 /* Do full blob inflation */ 5708 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 5709 poll_threads(); 5710 CU_ASSERT(g_bserrno == 0); 5711 5712 /* All clusters should be inflated (except one already allocated 5713 * in a top level blob) */ 5714 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 4); 5715 5716 /* Check if relation tree updated correctly */ 5717 count = 2; 5718 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5719 5720 /* snapshotid have one clone */ 5721 CU_ASSERT(count == 1); 5722 CU_ASSERT(ids[0] == snapshot2id); 5723 5724 /* snapshot2id have no clones */ 5725 count = 2; 5726 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5727 CU_ASSERT(count == 0); 5728 5729 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5730 } else { 5731 /* Decouple parent of blob */ 5732 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 5733 poll_threads(); 5734 CU_ASSERT(g_bserrno == 0); 5735 5736 /* Only one cluster from a parent should be inflated (second one 5737 * is covered by a cluster written on a top level blob, and 5738 * already allocated) */ 5739 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 1); 5740 5741 /* Check if relation tree updated correctly */ 5742 count = 2; 5743 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5744 5745 /* snapshotid have two clones now */ 5746 CU_ASSERT(count == 2); 5747 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5748 CU_ASSERT(ids[0] == snapshot2id || ids[1] == snapshot2id); 5749 5750 /* snapshot2id have no clones */ 5751 count = 2; 5752 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5753 CU_ASSERT(count == 0); 5754 5755 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5756 } 5757 5758 /* Try to delete snapshot2 (should pass) */ 5759 spdk_bs_delete_blob(bs, snapshot2id, blob_op_complete, NULL); 5760 poll_threads(); 5761 CU_ASSERT(g_bserrno == 0); 5762 5763 /* Try to delete base snapshot */ 5764 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5765 poll_threads(); 5766 CU_ASSERT(g_bserrno == 0); 5767 5768 /* Reopen blob after snapshot deletion */ 5769 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5770 poll_threads(); 5771 CU_ASSERT(g_bserrno == 0); 5772 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5773 blob = g_blob; 5774 5775 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5776 5777 /* Check data consistency on inflated blob */ 5778 memset(payload_read, 0xFF, payload_size); 5779 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5780 blob_op_complete, NULL); 5781 poll_threads(); 5782 CU_ASSERT(g_bserrno == 0); 5783 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5784 5785 spdk_blob_close(blob, blob_op_complete, NULL); 5786 poll_threads(); 5787 CU_ASSERT(g_bserrno == 0); 5788 5789 spdk_bs_free_io_channel(channel); 5790 poll_threads(); 5791 5792 /* Unload the blob store */ 5793 spdk_bs_unload(bs, bs_op_complete, NULL); 5794 poll_threads(); 5795 CU_ASSERT(g_bserrno == 0); 5796 g_bs = NULL; 5797 g_blob = NULL; 5798 g_blobid = 0; 5799 5800 free(payload_read); 5801 free(payload_write); 5802 free(payload_clone); 5803 } 5804 5805 static void 5806 blob_inflate_rw(void) 5807 { 5808 _blob_inflate_rw(false); 5809 _blob_inflate_rw(true); 5810 } 5811 5812 /** 5813 * Snapshot-clones relation test 5814 * 5815 * snapshot 5816 * | 5817 * +-----+-----+ 5818 * | | 5819 * blob(ro) snapshot2 5820 * | | 5821 * clone2 clone 5822 */ 5823 static void 5824 blob_relations(void) 5825 { 5826 struct spdk_blob_store *bs; 5827 struct spdk_bs_dev *dev; 5828 struct spdk_bs_opts bs_opts; 5829 struct spdk_blob_opts opts; 5830 struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2; 5831 spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2; 5832 int rc; 5833 size_t count; 5834 spdk_blob_id ids[10] = {}; 5835 5836 dev = init_dev(); 5837 spdk_bs_opts_init(&bs_opts); 5838 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5839 5840 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 5841 poll_threads(); 5842 CU_ASSERT(g_bserrno == 0); 5843 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5844 bs = g_bs; 5845 5846 /* 1. Create blob with 10 clusters */ 5847 5848 ut_spdk_blob_opts_init(&opts); 5849 opts.num_clusters = 10; 5850 5851 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5852 poll_threads(); 5853 CU_ASSERT(g_bserrno == 0); 5854 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5855 blobid = g_blobid; 5856 5857 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5858 poll_threads(); 5859 CU_ASSERT(g_bserrno == 0); 5860 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5861 blob = g_blob; 5862 5863 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5864 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5865 CU_ASSERT(!spdk_blob_is_clone(blob)); 5866 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob)); 5867 5868 /* blob should not have underlying snapshot nor clones */ 5869 CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID); 5870 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5871 count = SPDK_COUNTOF(ids); 5872 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5873 CU_ASSERT(rc == 0); 5874 CU_ASSERT(count == 0); 5875 5876 5877 /* 2. Create snapshot */ 5878 5879 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5880 poll_threads(); 5881 CU_ASSERT(g_bserrno == 0); 5882 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5883 snapshotid = g_blobid; 5884 5885 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5886 poll_threads(); 5887 CU_ASSERT(g_bserrno == 0); 5888 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5889 snapshot = g_blob; 5890 5891 CU_ASSERT(spdk_blob_is_read_only(snapshot)); 5892 CU_ASSERT(spdk_blob_is_snapshot(snapshot)); 5893 CU_ASSERT(!spdk_blob_is_clone(snapshot)); 5894 CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID); 5895 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5896 5897 /* Check if original blob is converted to the clone of snapshot */ 5898 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5899 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5900 CU_ASSERT(spdk_blob_is_clone(blob)); 5901 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5902 CU_ASSERT(blob->parent_id == snapshotid); 5903 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5904 5905 count = SPDK_COUNTOF(ids); 5906 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5907 CU_ASSERT(rc == 0); 5908 CU_ASSERT(count == 1); 5909 CU_ASSERT(ids[0] == blobid); 5910 5911 5912 /* 3. Create clone from snapshot */ 5913 5914 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 5915 poll_threads(); 5916 CU_ASSERT(g_bserrno == 0); 5917 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5918 cloneid = g_blobid; 5919 5920 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 5921 poll_threads(); 5922 CU_ASSERT(g_bserrno == 0); 5923 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5924 clone = g_blob; 5925 5926 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5927 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5928 CU_ASSERT(spdk_blob_is_clone(clone)); 5929 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5930 CU_ASSERT(clone->parent_id == snapshotid); 5931 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 5932 5933 count = SPDK_COUNTOF(ids); 5934 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5935 CU_ASSERT(rc == 0); 5936 CU_ASSERT(count == 0); 5937 5938 /* Check if clone is on the snapshot's list */ 5939 count = SPDK_COUNTOF(ids); 5940 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5941 CU_ASSERT(rc == 0); 5942 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5943 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 5944 5945 5946 /* 4. Create snapshot of the clone */ 5947 5948 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 5949 poll_threads(); 5950 CU_ASSERT(g_bserrno == 0); 5951 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5952 snapshotid2 = g_blobid; 5953 5954 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 5955 poll_threads(); 5956 CU_ASSERT(g_bserrno == 0); 5957 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5958 snapshot2 = g_blob; 5959 5960 CU_ASSERT(spdk_blob_is_read_only(snapshot2)); 5961 CU_ASSERT(spdk_blob_is_snapshot(snapshot2)); 5962 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 5963 CU_ASSERT(snapshot2->parent_id == snapshotid); 5964 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5965 5966 /* Check if clone is converted to the clone of snapshot2 and snapshot2 5967 * is a child of snapshot */ 5968 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5969 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5970 CU_ASSERT(spdk_blob_is_clone(clone)); 5971 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5972 CU_ASSERT(clone->parent_id == snapshotid2); 5973 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5974 5975 count = SPDK_COUNTOF(ids); 5976 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5977 CU_ASSERT(rc == 0); 5978 CU_ASSERT(count == 1); 5979 CU_ASSERT(ids[0] == cloneid); 5980 5981 5982 /* 5. Try to create clone from read only blob */ 5983 5984 /* Mark blob as read only */ 5985 spdk_blob_set_read_only(blob); 5986 spdk_blob_sync_md(blob, blob_op_complete, NULL); 5987 poll_threads(); 5988 CU_ASSERT(g_bserrno == 0); 5989 5990 /* Check if previously created blob is read only clone */ 5991 CU_ASSERT(spdk_blob_is_read_only(blob)); 5992 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5993 CU_ASSERT(spdk_blob_is_clone(blob)); 5994 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5995 5996 /* Create clone from read only blob */ 5997 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5998 poll_threads(); 5999 CU_ASSERT(g_bserrno == 0); 6000 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6001 cloneid2 = g_blobid; 6002 6003 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 6004 poll_threads(); 6005 CU_ASSERT(g_bserrno == 0); 6006 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6007 clone2 = g_blob; 6008 6009 CU_ASSERT(!spdk_blob_is_read_only(clone2)); 6010 CU_ASSERT(!spdk_blob_is_snapshot(clone2)); 6011 CU_ASSERT(spdk_blob_is_clone(clone2)); 6012 CU_ASSERT(spdk_blob_is_thin_provisioned(clone2)); 6013 6014 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 6015 6016 count = SPDK_COUNTOF(ids); 6017 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 6018 CU_ASSERT(rc == 0); 6019 6020 CU_ASSERT(count == 1); 6021 CU_ASSERT(ids[0] == cloneid2); 6022 6023 /* Close blobs */ 6024 6025 spdk_blob_close(clone2, blob_op_complete, NULL); 6026 poll_threads(); 6027 CU_ASSERT(g_bserrno == 0); 6028 6029 spdk_blob_close(blob, blob_op_complete, NULL); 6030 poll_threads(); 6031 CU_ASSERT(g_bserrno == 0); 6032 6033 spdk_blob_close(clone, blob_op_complete, NULL); 6034 poll_threads(); 6035 CU_ASSERT(g_bserrno == 0); 6036 6037 spdk_blob_close(snapshot, blob_op_complete, NULL); 6038 poll_threads(); 6039 CU_ASSERT(g_bserrno == 0); 6040 6041 spdk_blob_close(snapshot2, blob_op_complete, NULL); 6042 poll_threads(); 6043 CU_ASSERT(g_bserrno == 0); 6044 6045 /* Try to delete snapshot with more than 1 clone */ 6046 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 6047 poll_threads(); 6048 CU_ASSERT(g_bserrno != 0); 6049 6050 spdk_bs_unload(bs, bs_op_complete, NULL); 6051 poll_threads(); 6052 CU_ASSERT(g_bserrno == 0); 6053 g_bs = NULL; 6054 6055 /* Load an existing blob store */ 6056 dev = init_dev(); 6057 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 6058 6059 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 6060 poll_threads(); 6061 CU_ASSERT(g_bserrno == 0); 6062 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6063 bs = g_bs; 6064 6065 6066 /* NULL ids array should return number of clones in count */ 6067 count = SPDK_COUNTOF(ids); 6068 rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count); 6069 CU_ASSERT(rc == -ENOMEM); 6070 CU_ASSERT(count == 2); 6071 6072 /* incorrect array size */ 6073 count = 1; 6074 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 6075 CU_ASSERT(rc == -ENOMEM); 6076 CU_ASSERT(count == 2); 6077 6078 6079 /* Verify structure of loaded blob store */ 6080 6081 /* snapshot */ 6082 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 6083 6084 count = SPDK_COUNTOF(ids); 6085 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 6086 CU_ASSERT(rc == 0); 6087 CU_ASSERT(count == 2); 6088 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 6089 CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2); 6090 6091 /* blob */ 6092 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 6093 count = SPDK_COUNTOF(ids); 6094 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 6095 CU_ASSERT(rc == 0); 6096 CU_ASSERT(count == 1); 6097 CU_ASSERT(ids[0] == cloneid2); 6098 6099 /* clone */ 6100 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 6101 count = SPDK_COUNTOF(ids); 6102 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 6103 CU_ASSERT(rc == 0); 6104 CU_ASSERT(count == 0); 6105 6106 /* snapshot2 */ 6107 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 6108 count = SPDK_COUNTOF(ids); 6109 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6110 CU_ASSERT(rc == 0); 6111 CU_ASSERT(count == 1); 6112 CU_ASSERT(ids[0] == cloneid); 6113 6114 /* clone2 */ 6115 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 6116 count = SPDK_COUNTOF(ids); 6117 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 6118 CU_ASSERT(rc == 0); 6119 CU_ASSERT(count == 0); 6120 6121 /* Try to delete blob that user should not be able to remove */ 6122 6123 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 6124 poll_threads(); 6125 CU_ASSERT(g_bserrno != 0); 6126 6127 /* Remove all blobs */ 6128 6129 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 6130 poll_threads(); 6131 CU_ASSERT(g_bserrno == 0); 6132 6133 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6134 poll_threads(); 6135 CU_ASSERT(g_bserrno == 0); 6136 6137 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 6138 poll_threads(); 6139 CU_ASSERT(g_bserrno == 0); 6140 6141 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 6142 poll_threads(); 6143 CU_ASSERT(g_bserrno == 0); 6144 6145 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 6146 poll_threads(); 6147 CU_ASSERT(g_bserrno == 0); 6148 6149 spdk_bs_unload(bs, bs_op_complete, NULL); 6150 poll_threads(); 6151 CU_ASSERT(g_bserrno == 0); 6152 6153 g_bs = NULL; 6154 } 6155 6156 /** 6157 * Snapshot-clones relation test 2 6158 * 6159 * snapshot1 6160 * | 6161 * snapshot2 6162 * | 6163 * +-----+-----+ 6164 * | | 6165 * blob(ro) snapshot3 6166 * | | 6167 * | snapshot4 6168 * | | | 6169 * clone2 clone clone3 6170 */ 6171 static void 6172 blob_relations2(void) 6173 { 6174 struct spdk_blob_store *bs; 6175 struct spdk_bs_dev *dev; 6176 struct spdk_bs_opts bs_opts; 6177 struct spdk_blob_opts opts; 6178 struct spdk_blob *blob, *snapshot1, *snapshot2, *snapshot3, *snapshot4, *clone, *clone2; 6179 spdk_blob_id blobid, snapshotid1, snapshotid2, snapshotid3, snapshotid4, cloneid, cloneid2, 6180 cloneid3; 6181 int rc; 6182 size_t count; 6183 spdk_blob_id ids[10] = {}; 6184 6185 dev = init_dev(); 6186 spdk_bs_opts_init(&bs_opts); 6187 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 6188 6189 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 6190 poll_threads(); 6191 CU_ASSERT(g_bserrno == 0); 6192 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6193 bs = g_bs; 6194 6195 /* 1. Create blob with 10 clusters */ 6196 6197 ut_spdk_blob_opts_init(&opts); 6198 opts.num_clusters = 10; 6199 6200 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 6201 poll_threads(); 6202 CU_ASSERT(g_bserrno == 0); 6203 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6204 blobid = g_blobid; 6205 6206 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 6207 poll_threads(); 6208 CU_ASSERT(g_bserrno == 0); 6209 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6210 blob = g_blob; 6211 6212 /* 2. Create snapshot1 */ 6213 6214 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6215 poll_threads(); 6216 CU_ASSERT(g_bserrno == 0); 6217 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6218 snapshotid1 = g_blobid; 6219 6220 spdk_bs_open_blob(bs, snapshotid1, blob_op_with_handle_complete, NULL); 6221 poll_threads(); 6222 CU_ASSERT(g_bserrno == 0); 6223 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6224 snapshot1 = g_blob; 6225 6226 CU_ASSERT(snapshot1->parent_id == SPDK_BLOBID_INVALID); 6227 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid1) == SPDK_BLOBID_INVALID); 6228 6229 CU_ASSERT(blob->parent_id == snapshotid1); 6230 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1); 6231 6232 /* Check if blob is the clone of snapshot1 */ 6233 CU_ASSERT(blob->parent_id == snapshotid1); 6234 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1); 6235 6236 count = SPDK_COUNTOF(ids); 6237 rc = spdk_blob_get_clones(bs, snapshotid1, ids, &count); 6238 CU_ASSERT(rc == 0); 6239 CU_ASSERT(count == 1); 6240 CU_ASSERT(ids[0] == blobid); 6241 6242 /* 3. Create another snapshot */ 6243 6244 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6245 poll_threads(); 6246 CU_ASSERT(g_bserrno == 0); 6247 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6248 snapshotid2 = g_blobid; 6249 6250 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 6251 poll_threads(); 6252 CU_ASSERT(g_bserrno == 0); 6253 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6254 snapshot2 = g_blob; 6255 6256 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 6257 CU_ASSERT(snapshot2->parent_id == snapshotid1); 6258 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid1); 6259 6260 /* Check if snapshot2 is the clone of snapshot1 and blob 6261 * is a child of snapshot2 */ 6262 CU_ASSERT(blob->parent_id == snapshotid2); 6263 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2); 6264 6265 count = SPDK_COUNTOF(ids); 6266 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6267 CU_ASSERT(rc == 0); 6268 CU_ASSERT(count == 1); 6269 CU_ASSERT(ids[0] == blobid); 6270 6271 /* 4. Create clone from snapshot */ 6272 6273 spdk_bs_create_clone(bs, snapshotid2, NULL, blob_op_with_id_complete, NULL); 6274 poll_threads(); 6275 CU_ASSERT(g_bserrno == 0); 6276 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6277 cloneid = g_blobid; 6278 6279 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 6280 poll_threads(); 6281 CU_ASSERT(g_bserrno == 0); 6282 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6283 clone = g_blob; 6284 6285 CU_ASSERT(clone->parent_id == snapshotid2); 6286 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 6287 6288 /* Check if clone is on the snapshot's list */ 6289 count = SPDK_COUNTOF(ids); 6290 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6291 CU_ASSERT(rc == 0); 6292 CU_ASSERT(count == 2); 6293 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 6294 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 6295 6296 /* 5. Create snapshot of the clone */ 6297 6298 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 6299 poll_threads(); 6300 CU_ASSERT(g_bserrno == 0); 6301 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6302 snapshotid3 = g_blobid; 6303 6304 spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL); 6305 poll_threads(); 6306 CU_ASSERT(g_bserrno == 0); 6307 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6308 snapshot3 = g_blob; 6309 6310 CU_ASSERT(snapshot3->parent_id == snapshotid2); 6311 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2); 6312 6313 /* Check if clone is converted to the clone of snapshot3 and snapshot3 6314 * is a child of snapshot2 */ 6315 CU_ASSERT(clone->parent_id == snapshotid3); 6316 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 6317 6318 count = SPDK_COUNTOF(ids); 6319 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 6320 CU_ASSERT(rc == 0); 6321 CU_ASSERT(count == 1); 6322 CU_ASSERT(ids[0] == cloneid); 6323 6324 /* 6. Create another snapshot of the clone */ 6325 6326 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 6327 poll_threads(); 6328 CU_ASSERT(g_bserrno == 0); 6329 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6330 snapshotid4 = g_blobid; 6331 6332 spdk_bs_open_blob(bs, snapshotid4, blob_op_with_handle_complete, NULL); 6333 poll_threads(); 6334 CU_ASSERT(g_bserrno == 0); 6335 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6336 snapshot4 = g_blob; 6337 6338 CU_ASSERT(snapshot4->parent_id == snapshotid3); 6339 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid4) == snapshotid3); 6340 6341 /* Check if clone is converted to the clone of snapshot4 and snapshot4 6342 * is a child of snapshot3 */ 6343 CU_ASSERT(clone->parent_id == snapshotid4); 6344 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid4); 6345 6346 count = SPDK_COUNTOF(ids); 6347 rc = spdk_blob_get_clones(bs, snapshotid4, ids, &count); 6348 CU_ASSERT(rc == 0); 6349 CU_ASSERT(count == 1); 6350 CU_ASSERT(ids[0] == cloneid); 6351 6352 /* 7. Remove snapshot 4 */ 6353 6354 spdk_blob_close(snapshot4, blob_op_complete, NULL); 6355 poll_threads(); 6356 CU_ASSERT(g_bserrno == 0); 6357 6358 spdk_bs_delete_blob(bs, snapshotid4, blob_op_complete, NULL); 6359 poll_threads(); 6360 CU_ASSERT(g_bserrno == 0); 6361 6362 /* Check if relations are back to state from before creating snapshot 4 */ 6363 CU_ASSERT(clone->parent_id == snapshotid3); 6364 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 6365 6366 count = SPDK_COUNTOF(ids); 6367 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 6368 CU_ASSERT(rc == 0); 6369 CU_ASSERT(count == 1); 6370 CU_ASSERT(ids[0] == cloneid); 6371 6372 /* 8. Create second clone of snapshot 3 and try to remove snapshot 3 */ 6373 6374 spdk_bs_create_clone(bs, snapshotid3, NULL, blob_op_with_id_complete, NULL); 6375 poll_threads(); 6376 CU_ASSERT(g_bserrno == 0); 6377 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6378 cloneid3 = g_blobid; 6379 6380 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 6381 poll_threads(); 6382 CU_ASSERT(g_bserrno != 0); 6383 6384 /* 9. Open snapshot 3 again and try to remove it while clone 3 is closed */ 6385 6386 spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL); 6387 poll_threads(); 6388 CU_ASSERT(g_bserrno == 0); 6389 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6390 snapshot3 = g_blob; 6391 6392 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 6393 poll_threads(); 6394 CU_ASSERT(g_bserrno != 0); 6395 6396 spdk_blob_close(snapshot3, blob_op_complete, NULL); 6397 poll_threads(); 6398 CU_ASSERT(g_bserrno == 0); 6399 6400 spdk_bs_delete_blob(bs, cloneid3, blob_op_complete, NULL); 6401 poll_threads(); 6402 CU_ASSERT(g_bserrno == 0); 6403 6404 /* 10. Remove snapshot 1 */ 6405 6406 spdk_blob_close(snapshot1, blob_op_complete, NULL); 6407 poll_threads(); 6408 CU_ASSERT(g_bserrno == 0); 6409 6410 spdk_bs_delete_blob(bs, snapshotid1, blob_op_complete, NULL); 6411 poll_threads(); 6412 CU_ASSERT(g_bserrno == 0); 6413 6414 /* Check if relations are back to state from before creating snapshot 4 (before step 6) */ 6415 CU_ASSERT(snapshot2->parent_id == SPDK_BLOBID_INVALID); 6416 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID); 6417 6418 count = SPDK_COUNTOF(ids); 6419 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6420 CU_ASSERT(rc == 0); 6421 CU_ASSERT(count == 2); 6422 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 6423 CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3); 6424 6425 /* 11. Try to create clone from read only blob */ 6426 6427 /* Mark blob as read only */ 6428 spdk_blob_set_read_only(blob); 6429 spdk_blob_sync_md(blob, blob_op_complete, NULL); 6430 poll_threads(); 6431 CU_ASSERT(g_bserrno == 0); 6432 6433 /* Create clone from read only blob */ 6434 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6435 poll_threads(); 6436 CU_ASSERT(g_bserrno == 0); 6437 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6438 cloneid2 = g_blobid; 6439 6440 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 6441 poll_threads(); 6442 CU_ASSERT(g_bserrno == 0); 6443 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6444 clone2 = g_blob; 6445 6446 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 6447 6448 count = SPDK_COUNTOF(ids); 6449 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 6450 CU_ASSERT(rc == 0); 6451 CU_ASSERT(count == 1); 6452 CU_ASSERT(ids[0] == cloneid2); 6453 6454 /* Close blobs */ 6455 6456 spdk_blob_close(clone2, blob_op_complete, NULL); 6457 poll_threads(); 6458 CU_ASSERT(g_bserrno == 0); 6459 6460 spdk_blob_close(blob, blob_op_complete, NULL); 6461 poll_threads(); 6462 CU_ASSERT(g_bserrno == 0); 6463 6464 spdk_blob_close(clone, blob_op_complete, NULL); 6465 poll_threads(); 6466 CU_ASSERT(g_bserrno == 0); 6467 6468 spdk_blob_close(snapshot2, blob_op_complete, NULL); 6469 poll_threads(); 6470 CU_ASSERT(g_bserrno == 0); 6471 6472 spdk_blob_close(snapshot3, blob_op_complete, NULL); 6473 poll_threads(); 6474 CU_ASSERT(g_bserrno == 0); 6475 6476 spdk_bs_unload(bs, bs_op_complete, NULL); 6477 poll_threads(); 6478 CU_ASSERT(g_bserrno == 0); 6479 g_bs = NULL; 6480 6481 /* Load an existing blob store */ 6482 dev = init_dev(); 6483 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 6484 6485 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 6486 poll_threads(); 6487 CU_ASSERT(g_bserrno == 0); 6488 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6489 bs = g_bs; 6490 6491 /* Verify structure of loaded blob store */ 6492 6493 /* snapshot2 */ 6494 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID); 6495 6496 count = SPDK_COUNTOF(ids); 6497 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6498 CU_ASSERT(rc == 0); 6499 CU_ASSERT(count == 2); 6500 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 6501 CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3); 6502 6503 /* blob */ 6504 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2); 6505 count = SPDK_COUNTOF(ids); 6506 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 6507 CU_ASSERT(rc == 0); 6508 CU_ASSERT(count == 1); 6509 CU_ASSERT(ids[0] == cloneid2); 6510 6511 /* clone */ 6512 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 6513 count = SPDK_COUNTOF(ids); 6514 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 6515 CU_ASSERT(rc == 0); 6516 CU_ASSERT(count == 0); 6517 6518 /* snapshot3 */ 6519 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2); 6520 count = SPDK_COUNTOF(ids); 6521 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 6522 CU_ASSERT(rc == 0); 6523 CU_ASSERT(count == 1); 6524 CU_ASSERT(ids[0] == cloneid); 6525 6526 /* clone2 */ 6527 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 6528 count = SPDK_COUNTOF(ids); 6529 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 6530 CU_ASSERT(rc == 0); 6531 CU_ASSERT(count == 0); 6532 6533 /* Try to delete all blobs in the worse possible order */ 6534 6535 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6536 poll_threads(); 6537 CU_ASSERT(g_bserrno != 0); 6538 6539 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 6540 poll_threads(); 6541 CU_ASSERT(g_bserrno == 0); 6542 6543 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6544 poll_threads(); 6545 CU_ASSERT(g_bserrno != 0); 6546 6547 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 6548 poll_threads(); 6549 CU_ASSERT(g_bserrno == 0); 6550 6551 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6552 poll_threads(); 6553 CU_ASSERT(g_bserrno == 0); 6554 6555 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 6556 poll_threads(); 6557 CU_ASSERT(g_bserrno == 0); 6558 6559 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 6560 poll_threads(); 6561 CU_ASSERT(g_bserrno == 0); 6562 6563 spdk_bs_unload(bs, bs_op_complete, NULL); 6564 poll_threads(); 6565 CU_ASSERT(g_bserrno == 0); 6566 6567 g_bs = NULL; 6568 } 6569 6570 static void 6571 blob_delete_snapshot_power_failure(void) 6572 { 6573 struct spdk_blob_store *bs; 6574 struct spdk_bs_dev *dev; 6575 struct spdk_blob_opts opts; 6576 struct spdk_blob *blob, *snapshot; 6577 struct spdk_power_failure_thresholds thresholds = {}; 6578 spdk_blob_id blobid, snapshotid; 6579 const void *value; 6580 size_t value_len; 6581 size_t count; 6582 spdk_blob_id ids[3] = {}; 6583 int rc; 6584 bool deleted = false; 6585 6586 dev = init_dev(); 6587 6588 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 6589 poll_threads(); 6590 CU_ASSERT(g_bserrno == 0); 6591 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6592 bs = g_bs; 6593 6594 /* Create blob */ 6595 ut_spdk_blob_opts_init(&opts); 6596 opts.num_clusters = 10; 6597 6598 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 6599 poll_threads(); 6600 CU_ASSERT(g_bserrno == 0); 6601 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6602 blobid = g_blobid; 6603 6604 /* Create snapshot */ 6605 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6606 poll_threads(); 6607 CU_ASSERT(g_bserrno == 0); 6608 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6609 snapshotid = g_blobid; 6610 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6611 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6612 6613 thresholds.general_threshold = 1; 6614 while (!deleted) { 6615 dev_set_power_failure_thresholds(thresholds); 6616 6617 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 6618 poll_threads(); 6619 6620 /* Do not shut down cleanly. Assumption is that after snapshot deletion 6621 * reports success, changes to both blobs should already persisted. */ 6622 _spdk_bs_free(bs); 6623 6624 dev_reset_power_failure_event(); 6625 6626 dev = init_dev(); 6627 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 6628 poll_threads(); 6629 CU_ASSERT(g_bserrno == 0); 6630 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6631 bs = g_bs; 6632 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6633 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6634 6635 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 6636 poll_threads(); 6637 CU_ASSERT(g_bserrno == 0); 6638 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6639 blob = g_blob; 6640 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true); 6641 6642 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 6643 poll_threads(); 6644 6645 if (g_bserrno == 0) { 6646 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6647 snapshot = g_blob; 6648 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 6649 count = SPDK_COUNTOF(ids); 6650 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 6651 CU_ASSERT(rc == 0); 6652 CU_ASSERT(count == 1); 6653 CU_ASSERT(ids[0] == blobid); 6654 rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_PENDING_REMOVAL, &value, &value_len); 6655 CU_ASSERT(rc != 0); 6656 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(snapshot) == false); 6657 6658 spdk_blob_close(snapshot, blob_op_complete, NULL); 6659 poll_threads(); 6660 CU_ASSERT(g_bserrno == 0); 6661 } else { 6662 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 6663 deleted = true; 6664 } 6665 6666 spdk_blob_close(blob, blob_op_complete, NULL); 6667 poll_threads(); 6668 CU_ASSERT(g_bserrno == 0); 6669 6670 /* Reload blobstore to have the same starting conditions (as the previous blobstore load 6671 * may trigger cleanup after power failure or may not) */ 6672 spdk_bs_unload(bs, bs_op_complete, NULL); 6673 poll_threads(); 6674 CU_ASSERT(g_bserrno == 0); 6675 6676 dev = init_dev(); 6677 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 6678 poll_threads(); 6679 CU_ASSERT(g_bserrno == 0); 6680 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6681 bs = g_bs; 6682 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6683 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6684 6685 thresholds.general_threshold++; 6686 } 6687 6688 spdk_bs_unload(bs, bs_op_complete, NULL); 6689 poll_threads(); 6690 CU_ASSERT(g_bserrno == 0); 6691 g_bs = NULL; 6692 } 6693 6694 static void 6695 blob_create_snapshot_power_failure(void) 6696 { 6697 struct spdk_blob_store *bs; 6698 struct spdk_bs_dev *dev; 6699 struct spdk_blob_opts opts; 6700 struct spdk_blob *blob, *snapshot; 6701 struct spdk_power_failure_thresholds thresholds = {}; 6702 spdk_blob_id blobid, snapshotid; 6703 const void *value; 6704 size_t value_len; 6705 size_t count; 6706 spdk_blob_id ids[3] = {}; 6707 int rc; 6708 bool created = false; 6709 6710 dev = init_dev(); 6711 6712 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 6713 poll_threads(); 6714 CU_ASSERT(g_bserrno == 0); 6715 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6716 bs = g_bs; 6717 6718 /* Create blob */ 6719 ut_spdk_blob_opts_init(&opts); 6720 opts.num_clusters = 10; 6721 6722 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 6723 poll_threads(); 6724 CU_ASSERT(g_bserrno == 0); 6725 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6726 blobid = g_blobid; 6727 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6728 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6729 6730 thresholds.general_threshold = 1; 6731 while (!created) { 6732 dev_set_power_failure_thresholds(thresholds); 6733 6734 /* Create snapshot */ 6735 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6736 poll_threads(); 6737 snapshotid = g_blobid; 6738 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6739 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6740 6741 /* Do not shut down cleanly. Assumption is that after create snapshot 6742 * reports success, both blobs should be power-fail safe. */ 6743 _spdk_bs_free(bs); 6744 6745 dev_reset_power_failure_event(); 6746 6747 dev = init_dev(); 6748 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 6749 poll_threads(); 6750 CU_ASSERT(g_bserrno == 0); 6751 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6752 bs = g_bs; 6753 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6754 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6755 6756 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 6757 poll_threads(); 6758 CU_ASSERT(g_bserrno == 0); 6759 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6760 blob = g_blob; 6761 6762 if (snapshotid != SPDK_BLOBID_INVALID) { 6763 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 6764 poll_threads(); 6765 } 6766 6767 if ((snapshotid != SPDK_BLOBID_INVALID) && (g_bserrno == 0)) { 6768 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6769 snapshot = g_blob; 6770 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true); 6771 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(snapshot) == false); 6772 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 6773 count = SPDK_COUNTOF(ids); 6774 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 6775 CU_ASSERT(rc == 0); 6776 CU_ASSERT(count == 1); 6777 CU_ASSERT(ids[0] == blobid); 6778 rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_IN_PROGRESS, &value, &value_len); 6779 CU_ASSERT(rc != 0); 6780 6781 spdk_blob_close(snapshot, blob_op_complete, NULL); 6782 poll_threads(); 6783 CU_ASSERT(g_bserrno == 0); 6784 created = true; 6785 } else { 6786 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 6787 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == false); 6788 } 6789 6790 spdk_blob_close(blob, blob_op_complete, NULL); 6791 poll_threads(); 6792 CU_ASSERT(g_bserrno == 0); 6793 6794 /* Reload blobstore to have the same starting conditions (as the previous blobstore load 6795 * may trigger cleanup after power failure or may not) */ 6796 spdk_bs_unload(bs, bs_op_complete, NULL); 6797 poll_threads(); 6798 CU_ASSERT(g_bserrno == 0); 6799 6800 dev = init_dev(); 6801 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 6802 poll_threads(); 6803 CU_ASSERT(g_bserrno == 0); 6804 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6805 bs = g_bs; 6806 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6807 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6808 6809 thresholds.general_threshold++; 6810 } 6811 6812 spdk_bs_unload(bs, bs_op_complete, NULL); 6813 poll_threads(); 6814 CU_ASSERT(g_bserrno == 0); 6815 g_bs = NULL; 6816 } 6817 6818 static void 6819 test_io_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6820 { 6821 uint8_t payload_ff[64 * 512]; 6822 uint8_t payload_aa[64 * 512]; 6823 uint8_t payload_00[64 * 512]; 6824 uint8_t *cluster0, *cluster1; 6825 6826 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6827 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6828 memset(payload_00, 0x00, sizeof(payload_00)); 6829 6830 /* Try to perform I/O with io unit = 512 */ 6831 spdk_blob_io_write(blob, channel, payload_ff, 0, 1, blob_op_complete, NULL); 6832 poll_threads(); 6833 CU_ASSERT(g_bserrno == 0); 6834 6835 /* If thin provisioned is set cluster should be allocated now */ 6836 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 6837 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6838 6839 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 6840 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 6841 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6842 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6843 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 6844 6845 /* Verify write with offset on first page */ 6846 spdk_blob_io_write(blob, channel, payload_ff, 2, 1, blob_op_complete, NULL); 6847 poll_threads(); 6848 CU_ASSERT(g_bserrno == 0); 6849 6850 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6851 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6852 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6853 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6854 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6855 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 6856 6857 /* Verify write with offset on first page */ 6858 spdk_blob_io_write(blob, channel, payload_ff, 4, 4, blob_op_complete, NULL); 6859 poll_threads(); 6860 6861 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6862 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6863 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6864 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6865 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6866 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 6867 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 6868 6869 /* Verify write with offset on second page */ 6870 spdk_blob_io_write(blob, channel, payload_ff, 8, 4, blob_op_complete, NULL); 6871 poll_threads(); 6872 6873 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 6874 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6875 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6876 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6877 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6878 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 6879 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6880 6881 /* Verify write across multiple pages */ 6882 spdk_blob_io_write(blob, channel, payload_aa, 4, 8, blob_op_complete, NULL); 6883 poll_threads(); 6884 6885 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 6886 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6887 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6888 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6889 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6890 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6891 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6892 6893 /* Verify write across multiple clusters */ 6894 spdk_blob_io_write(blob, channel, payload_ff, 28, 8, blob_op_complete, NULL); 6895 poll_threads(); 6896 6897 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6898 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6899 6900 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6901 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6902 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6903 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6904 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6905 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6906 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6907 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6908 6909 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6910 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 6911 6912 /* Verify write to second cluster */ 6913 spdk_blob_io_write(blob, channel, payload_ff, 32 + 12, 2, blob_op_complete, NULL); 6914 poll_threads(); 6915 6916 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6917 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6918 6919 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6920 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 6921 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6922 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6923 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6924 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6925 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6926 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6927 6928 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6929 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 6930 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 6931 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 6932 } 6933 6934 static void 6935 test_io_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6936 { 6937 uint8_t payload_read[64 * 512]; 6938 uint8_t payload_ff[64 * 512]; 6939 uint8_t payload_aa[64 * 512]; 6940 uint8_t payload_00[64 * 512]; 6941 6942 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6943 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6944 memset(payload_00, 0x00, sizeof(payload_00)); 6945 6946 /* Read only first io unit */ 6947 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6948 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6949 * payload_read: F000 0000 | 0000 0000 ... */ 6950 memset(payload_read, 0x00, sizeof(payload_read)); 6951 spdk_blob_io_read(blob, channel, payload_read, 0, 1, blob_op_complete, NULL); 6952 poll_threads(); 6953 CU_ASSERT(g_bserrno == 0); 6954 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6955 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 6956 6957 /* Read four io_units starting from offset = 2 6958 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6959 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6960 * payload_read: F0AA 0000 | 0000 0000 ... */ 6961 6962 memset(payload_read, 0x00, sizeof(payload_read)); 6963 spdk_blob_io_read(blob, channel, payload_read, 2, 4, blob_op_complete, NULL); 6964 poll_threads(); 6965 CU_ASSERT(g_bserrno == 0); 6966 6967 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6968 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6969 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 6970 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 6971 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6972 6973 /* Read eight io_units across multiple pages 6974 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6975 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6976 * payload_read: AAAA AAAA | 0000 0000 ... */ 6977 memset(payload_read, 0x00, sizeof(payload_read)); 6978 spdk_blob_io_read(blob, channel, payload_read, 4, 8, blob_op_complete, NULL); 6979 poll_threads(); 6980 CU_ASSERT(g_bserrno == 0); 6981 6982 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 6983 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6984 6985 /* Read eight io_units across multiple clusters 6986 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 6987 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6988 * payload_read: FFFF FFFF | 0000 0000 ... */ 6989 memset(payload_read, 0x00, sizeof(payload_read)); 6990 spdk_blob_io_read(blob, channel, payload_read, 28, 8, blob_op_complete, NULL); 6991 poll_threads(); 6992 CU_ASSERT(g_bserrno == 0); 6993 6994 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 6995 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6996 6997 /* Read four io_units from second cluster 6998 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6999 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 7000 * payload_read: 00FF 0000 | 0000 0000 ... */ 7001 memset(payload_read, 0x00, sizeof(payload_read)); 7002 spdk_blob_io_read(blob, channel, payload_read, 32 + 10, 4, blob_op_complete, NULL); 7003 poll_threads(); 7004 CU_ASSERT(g_bserrno == 0); 7005 7006 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 7007 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 7008 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 7009 7010 /* Read second cluster 7011 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7012 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 7013 * payload_read: FFFF 0000 | 0000 FF00 ... */ 7014 memset(payload_read, 0x00, sizeof(payload_read)); 7015 spdk_blob_io_read(blob, channel, payload_read, 32, 32, blob_op_complete, NULL); 7016 poll_threads(); 7017 CU_ASSERT(g_bserrno == 0); 7018 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 7019 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 7020 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 7021 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 7022 7023 /* Read whole two clusters 7024 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 7025 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 7026 memset(payload_read, 0x00, sizeof(payload_read)); 7027 spdk_blob_io_read(blob, channel, payload_read, 0, 64, blob_op_complete, NULL); 7028 poll_threads(); 7029 CU_ASSERT(g_bserrno == 0); 7030 7031 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 7032 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 7033 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 7034 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 7035 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 7036 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 7037 7038 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 7039 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 7040 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 7041 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 7042 } 7043 7044 7045 static void 7046 test_io_unmap(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 7047 { 7048 uint8_t payload_ff[64 * 512]; 7049 uint8_t payload_aa[64 * 512]; 7050 uint8_t payload_00[64 * 512]; 7051 uint8_t *cluster0, *cluster1; 7052 7053 memset(payload_ff, 0xFF, sizeof(payload_ff)); 7054 memset(payload_aa, 0xAA, sizeof(payload_aa)); 7055 memset(payload_00, 0x00, sizeof(payload_00)); 7056 7057 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 7058 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 7059 7060 /* Unmap */ 7061 spdk_blob_io_unmap(blob, channel, 0, 64, blob_op_complete, NULL); 7062 poll_threads(); 7063 7064 CU_ASSERT(g_bserrno == 0); 7065 7066 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 7067 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 7068 } 7069 7070 static void 7071 test_io_zeroes(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 7072 { 7073 uint8_t payload_ff[64 * 512]; 7074 uint8_t payload_aa[64 * 512]; 7075 uint8_t payload_00[64 * 512]; 7076 uint8_t *cluster0, *cluster1; 7077 7078 memset(payload_ff, 0xFF, sizeof(payload_ff)); 7079 memset(payload_aa, 0xAA, sizeof(payload_aa)); 7080 memset(payload_00, 0x00, sizeof(payload_00)); 7081 7082 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 7083 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 7084 7085 /* Write zeroes */ 7086 spdk_blob_io_write_zeroes(blob, channel, 0, 64, blob_op_complete, NULL); 7087 poll_threads(); 7088 7089 CU_ASSERT(g_bserrno == 0); 7090 7091 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 7092 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 7093 } 7094 7095 7096 static void 7097 test_iov_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 7098 { 7099 uint8_t payload_ff[64 * 512]; 7100 uint8_t payload_aa[64 * 512]; 7101 uint8_t payload_00[64 * 512]; 7102 uint8_t *cluster0, *cluster1; 7103 struct iovec iov[4]; 7104 7105 memset(payload_ff, 0xFF, sizeof(payload_ff)); 7106 memset(payload_aa, 0xAA, sizeof(payload_aa)); 7107 memset(payload_00, 0x00, sizeof(payload_00)); 7108 7109 /* Try to perform I/O with io unit = 512 */ 7110 iov[0].iov_base = payload_ff; 7111 iov[0].iov_len = 1 * 512; 7112 spdk_blob_io_writev(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 7113 poll_threads(); 7114 CU_ASSERT(g_bserrno == 0); 7115 7116 /* If thin provisioned is set cluster should be allocated now */ 7117 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 7118 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 7119 7120 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 7121 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 7122 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 7123 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7124 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 7125 7126 /* Verify write with offset on first page */ 7127 iov[0].iov_base = payload_ff; 7128 iov[0].iov_len = 1 * 512; 7129 spdk_blob_io_writev(blob, channel, iov, 1, 2, 1, blob_op_complete, NULL); 7130 poll_threads(); 7131 CU_ASSERT(g_bserrno == 0); 7132 7133 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 7134 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7135 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 7136 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 7137 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 7138 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 7139 7140 /* Verify write with offset on first page */ 7141 iov[0].iov_base = payload_ff; 7142 iov[0].iov_len = 4 * 512; 7143 spdk_blob_io_writev(blob, channel, iov, 1, 4, 4, blob_op_complete, NULL); 7144 poll_threads(); 7145 7146 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 7147 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7148 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 7149 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 7150 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 7151 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 7152 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 7153 7154 /* Verify write with offset on second page */ 7155 iov[0].iov_base = payload_ff; 7156 iov[0].iov_len = 4 * 512; 7157 spdk_blob_io_writev(blob, channel, iov, 1, 8, 4, blob_op_complete, NULL); 7158 poll_threads(); 7159 7160 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 7161 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7162 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 7163 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 7164 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 7165 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 7166 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 7167 7168 /* Verify write across multiple pages */ 7169 iov[0].iov_base = payload_aa; 7170 iov[0].iov_len = 8 * 512; 7171 spdk_blob_io_writev(blob, channel, iov, 1, 4, 8, blob_op_complete, NULL); 7172 poll_threads(); 7173 7174 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 7175 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7176 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 7177 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 7178 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 7179 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 7180 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 7181 7182 /* Verify write across multiple clusters */ 7183 7184 iov[0].iov_base = payload_ff; 7185 iov[0].iov_len = 8 * 512; 7186 spdk_blob_io_writev(blob, channel, iov, 1, 28, 8, blob_op_complete, NULL); 7187 poll_threads(); 7188 7189 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 7190 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 7191 7192 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7193 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 7194 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7195 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 7196 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 7197 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 7198 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 7199 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 16 * 512) == 0); 7200 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 7201 7202 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 7203 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 7204 7205 /* Verify write to second cluster */ 7206 7207 iov[0].iov_base = payload_ff; 7208 iov[0].iov_len = 2 * 512; 7209 spdk_blob_io_writev(blob, channel, iov, 1, 32 + 12, 2, blob_op_complete, NULL); 7210 poll_threads(); 7211 7212 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 7213 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 7214 7215 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7216 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 7217 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7218 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 7219 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 7220 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 7221 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 7222 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 7223 7224 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 7225 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 7226 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 7227 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 7228 } 7229 7230 static void 7231 test_iov_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 7232 { 7233 uint8_t payload_read[64 * 512]; 7234 uint8_t payload_ff[64 * 512]; 7235 uint8_t payload_aa[64 * 512]; 7236 uint8_t payload_00[64 * 512]; 7237 struct iovec iov[4]; 7238 7239 memset(payload_ff, 0xFF, sizeof(payload_ff)); 7240 memset(payload_aa, 0xAA, sizeof(payload_aa)); 7241 memset(payload_00, 0x00, sizeof(payload_00)); 7242 7243 /* Read only first io unit */ 7244 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7245 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 7246 * payload_read: F000 0000 | 0000 0000 ... */ 7247 memset(payload_read, 0x00, sizeof(payload_read)); 7248 iov[0].iov_base = payload_read; 7249 iov[0].iov_len = 1 * 512; 7250 spdk_blob_io_readv(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 7251 poll_threads(); 7252 7253 CU_ASSERT(g_bserrno == 0); 7254 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 7255 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 7256 7257 /* Read four io_units starting from offset = 2 7258 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7259 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 7260 * payload_read: F0AA 0000 | 0000 0000 ... */ 7261 7262 memset(payload_read, 0x00, sizeof(payload_read)); 7263 iov[0].iov_base = payload_read; 7264 iov[0].iov_len = 4 * 512; 7265 spdk_blob_io_readv(blob, channel, iov, 1, 2, 4, blob_op_complete, NULL); 7266 poll_threads(); 7267 CU_ASSERT(g_bserrno == 0); 7268 7269 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 7270 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 7271 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 7272 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 7273 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 7274 7275 /* Read eight io_units across multiple pages 7276 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 7277 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 7278 * payload_read: AAAA AAAA | 0000 0000 ... */ 7279 memset(payload_read, 0x00, sizeof(payload_read)); 7280 iov[0].iov_base = payload_read; 7281 iov[0].iov_len = 4 * 512; 7282 iov[1].iov_base = payload_read + 4 * 512; 7283 iov[1].iov_len = 4 * 512; 7284 spdk_blob_io_readv(blob, channel, iov, 2, 4, 8, blob_op_complete, NULL); 7285 poll_threads(); 7286 CU_ASSERT(g_bserrno == 0); 7287 7288 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 7289 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 7290 7291 /* Read eight io_units across multiple clusters 7292 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 7293 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 7294 * payload_read: FFFF FFFF | 0000 0000 ... */ 7295 memset(payload_read, 0x00, sizeof(payload_read)); 7296 iov[0].iov_base = payload_read; 7297 iov[0].iov_len = 2 * 512; 7298 iov[1].iov_base = payload_read + 2 * 512; 7299 iov[1].iov_len = 2 * 512; 7300 iov[2].iov_base = payload_read + 4 * 512; 7301 iov[2].iov_len = 2 * 512; 7302 iov[3].iov_base = payload_read + 6 * 512; 7303 iov[3].iov_len = 2 * 512; 7304 spdk_blob_io_readv(blob, channel, iov, 4, 28, 8, blob_op_complete, NULL); 7305 poll_threads(); 7306 CU_ASSERT(g_bserrno == 0); 7307 7308 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 7309 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 7310 7311 /* Read four io_units from second cluster 7312 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7313 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 7314 * payload_read: 00FF 0000 | 0000 0000 ... */ 7315 memset(payload_read, 0x00, sizeof(payload_read)); 7316 iov[0].iov_base = payload_read; 7317 iov[0].iov_len = 1 * 512; 7318 iov[1].iov_base = payload_read + 1 * 512; 7319 iov[1].iov_len = 3 * 512; 7320 spdk_blob_io_readv(blob, channel, iov, 2, 32 + 10, 4, blob_op_complete, NULL); 7321 poll_threads(); 7322 CU_ASSERT(g_bserrno == 0); 7323 7324 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 7325 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 7326 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 7327 7328 /* Read second cluster 7329 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7330 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 7331 * payload_read: FFFF 0000 | 0000 FF00 ... */ 7332 memset(payload_read, 0x00, sizeof(payload_read)); 7333 iov[0].iov_base = payload_read; 7334 iov[0].iov_len = 1 * 512; 7335 iov[1].iov_base = payload_read + 1 * 512; 7336 iov[1].iov_len = 2 * 512; 7337 iov[2].iov_base = payload_read + 3 * 512; 7338 iov[2].iov_len = 4 * 512; 7339 iov[3].iov_base = payload_read + 7 * 512; 7340 iov[3].iov_len = 25 * 512; 7341 spdk_blob_io_readv(blob, channel, iov, 4, 32, 32, blob_op_complete, NULL); 7342 poll_threads(); 7343 CU_ASSERT(g_bserrno == 0); 7344 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 7345 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 7346 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 7347 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 7348 7349 /* Read whole two clusters 7350 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 7351 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 7352 memset(payload_read, 0x00, sizeof(payload_read)); 7353 iov[0].iov_base = payload_read; 7354 iov[0].iov_len = 1 * 512; 7355 iov[1].iov_base = payload_read + 1 * 512; 7356 iov[1].iov_len = 8 * 512; 7357 iov[2].iov_base = payload_read + 9 * 512; 7358 iov[2].iov_len = 16 * 512; 7359 iov[3].iov_base = payload_read + 25 * 512; 7360 iov[3].iov_len = 39 * 512; 7361 spdk_blob_io_readv(blob, channel, iov, 4, 0, 64, blob_op_complete, NULL); 7362 poll_threads(); 7363 CU_ASSERT(g_bserrno == 0); 7364 7365 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 7366 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 7367 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 7368 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 7369 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 7370 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 7371 7372 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 7373 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 7374 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 7375 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 7376 } 7377 7378 static void 7379 blob_io_unit(void) 7380 { 7381 struct spdk_bs_opts bsopts; 7382 struct spdk_blob_opts opts; 7383 struct spdk_blob_store *bs; 7384 struct spdk_bs_dev *dev; 7385 struct spdk_blob *blob, *snapshot, *clone; 7386 spdk_blob_id blobid; 7387 struct spdk_io_channel *channel; 7388 7389 /* Create dev with 512 bytes io unit size */ 7390 7391 spdk_bs_opts_init(&bsopts); 7392 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 7393 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 7394 7395 /* Try to initialize a new blob store with unsupported io_unit */ 7396 dev = init_dev(); 7397 dev->blocklen = 512; 7398 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 7399 7400 /* Initialize a new blob store */ 7401 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 7402 poll_threads(); 7403 CU_ASSERT(g_bserrno == 0); 7404 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7405 bs = g_bs; 7406 7407 CU_ASSERT(spdk_bs_get_io_unit_size(bs) == 512); 7408 channel = spdk_bs_alloc_io_channel(bs); 7409 7410 /* Create thick provisioned blob */ 7411 ut_spdk_blob_opts_init(&opts); 7412 opts.thin_provision = false; 7413 opts.num_clusters = 32; 7414 7415 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 7416 poll_threads(); 7417 7418 CU_ASSERT(g_bserrno == 0); 7419 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7420 blobid = g_blobid; 7421 7422 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7423 poll_threads(); 7424 CU_ASSERT(g_bserrno == 0); 7425 CU_ASSERT(g_blob != NULL); 7426 blob = g_blob; 7427 7428 test_io_write(dev, blob, channel); 7429 test_io_read(dev, blob, channel); 7430 test_io_zeroes(dev, blob, channel); 7431 7432 test_iov_write(dev, blob, channel); 7433 test_iov_read(dev, blob, channel); 7434 7435 test_io_unmap(dev, blob, channel); 7436 7437 spdk_blob_close(blob, blob_op_complete, NULL); 7438 poll_threads(); 7439 CU_ASSERT(g_bserrno == 0); 7440 blob = NULL; 7441 g_blob = NULL; 7442 7443 /* Create thin provisioned blob */ 7444 7445 ut_spdk_blob_opts_init(&opts); 7446 opts.thin_provision = true; 7447 opts.num_clusters = 32; 7448 7449 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 7450 poll_threads(); 7451 CU_ASSERT(g_bserrno == 0); 7452 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7453 blobid = g_blobid; 7454 7455 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7456 poll_threads(); 7457 CU_ASSERT(g_bserrno == 0); 7458 CU_ASSERT(g_blob != NULL); 7459 blob = g_blob; 7460 7461 test_io_write(dev, blob, channel); 7462 test_io_read(dev, blob, channel); 7463 7464 test_io_zeroes(dev, blob, channel); 7465 7466 test_iov_write(dev, blob, channel); 7467 test_iov_read(dev, blob, channel); 7468 7469 /* Create snapshot */ 7470 7471 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 7472 poll_threads(); 7473 CU_ASSERT(g_bserrno == 0); 7474 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7475 blobid = g_blobid; 7476 7477 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7478 poll_threads(); 7479 CU_ASSERT(g_bserrno == 0); 7480 CU_ASSERT(g_blob != NULL); 7481 snapshot = g_blob; 7482 7483 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 7484 poll_threads(); 7485 CU_ASSERT(g_bserrno == 0); 7486 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7487 blobid = g_blobid; 7488 7489 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7490 poll_threads(); 7491 CU_ASSERT(g_bserrno == 0); 7492 CU_ASSERT(g_blob != NULL); 7493 clone = g_blob; 7494 7495 test_io_read(dev, blob, channel); 7496 test_io_read(dev, snapshot, channel); 7497 test_io_read(dev, clone, channel); 7498 7499 test_iov_read(dev, blob, channel); 7500 test_iov_read(dev, snapshot, channel); 7501 test_iov_read(dev, clone, channel); 7502 7503 /* Inflate clone */ 7504 7505 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 7506 poll_threads(); 7507 7508 CU_ASSERT(g_bserrno == 0); 7509 7510 test_io_read(dev, clone, channel); 7511 7512 test_io_unmap(dev, clone, channel); 7513 7514 test_iov_write(dev, clone, channel); 7515 test_iov_read(dev, clone, channel); 7516 7517 spdk_blob_close(blob, blob_op_complete, NULL); 7518 spdk_blob_close(snapshot, blob_op_complete, NULL); 7519 spdk_blob_close(clone, blob_op_complete, NULL); 7520 poll_threads(); 7521 CU_ASSERT(g_bserrno == 0); 7522 blob = NULL; 7523 g_blob = NULL; 7524 7525 spdk_bs_free_io_channel(channel); 7526 poll_threads(); 7527 7528 /* Unload the blob store */ 7529 spdk_bs_unload(bs, bs_op_complete, NULL); 7530 poll_threads(); 7531 CU_ASSERT(g_bserrno == 0); 7532 g_bs = NULL; 7533 g_blob = NULL; 7534 g_blobid = 0; 7535 } 7536 7537 static void 7538 blob_io_unit_compatiblity(void) 7539 { 7540 struct spdk_bs_opts bsopts; 7541 struct spdk_blob_store *bs; 7542 struct spdk_bs_dev *dev; 7543 struct spdk_bs_super_block *super; 7544 7545 /* Create dev with 512 bytes io unit size */ 7546 7547 spdk_bs_opts_init(&bsopts); 7548 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 7549 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 7550 7551 /* Try to initialize a new blob store with unsupported io_unit */ 7552 dev = init_dev(); 7553 dev->blocklen = 512; 7554 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 7555 7556 /* Initialize a new blob store */ 7557 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 7558 poll_threads(); 7559 CU_ASSERT(g_bserrno == 0); 7560 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7561 bs = g_bs; 7562 7563 CU_ASSERT(spdk_bs_get_io_unit_size(bs) == 512); 7564 7565 /* Unload the blob store */ 7566 spdk_bs_unload(bs, bs_op_complete, NULL); 7567 poll_threads(); 7568 CU_ASSERT(g_bserrno == 0); 7569 7570 /* Modify super block to behave like older version. 7571 * Check if loaded io unit size equals SPDK_BS_PAGE_SIZE */ 7572 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 7573 super->io_unit_size = 0; 7574 super->crc = _spdk_blob_md_page_calc_crc(super); 7575 7576 dev = init_dev(); 7577 dev->blocklen = 512; 7578 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 7579 7580 spdk_bs_load(dev, &bsopts, bs_op_with_handle_complete, NULL); 7581 poll_threads(); 7582 CU_ASSERT(g_bserrno == 0); 7583 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7584 bs = g_bs; 7585 7586 CU_ASSERT(spdk_bs_get_io_unit_size(bs) == SPDK_BS_PAGE_SIZE); 7587 7588 /* Unload the blob store */ 7589 spdk_bs_unload(bs, bs_op_complete, NULL); 7590 poll_threads(); 7591 CU_ASSERT(g_bserrno == 0); 7592 7593 g_bs = NULL; 7594 g_blob = NULL; 7595 g_blobid = 0; 7596 } 7597 7598 static void 7599 blob_simultaneous_operations(void) 7600 { 7601 struct spdk_blob_store *bs; 7602 struct spdk_bs_dev *dev; 7603 struct spdk_blob_opts opts; 7604 struct spdk_blob *blob, *snapshot; 7605 spdk_blob_id blobid, snapshotid; 7606 struct spdk_io_channel *channel; 7607 7608 dev = init_dev(); 7609 7610 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 7611 poll_threads(); 7612 CU_ASSERT(g_bserrno == 0); 7613 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7614 bs = g_bs; 7615 7616 channel = spdk_bs_alloc_io_channel(bs); 7617 SPDK_CU_ASSERT_FATAL(channel != NULL); 7618 7619 ut_spdk_blob_opts_init(&opts); 7620 opts.num_clusters = 10; 7621 7622 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 7623 poll_threads(); 7624 CU_ASSERT(g_bserrno == 0); 7625 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7626 blobid = g_blobid; 7627 7628 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7629 poll_threads(); 7630 CU_ASSERT(g_bserrno == 0); 7631 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7632 blob = g_blob; 7633 7634 /* Create snapshot and try to remove blob in the same time: 7635 * - snapshot should be created successfully 7636 * - delete operation should fail w -EBUSY */ 7637 CU_ASSERT(blob->locked_operation_in_progress == false); 7638 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 7639 CU_ASSERT(blob->locked_operation_in_progress == true); 7640 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7641 CU_ASSERT(blob->locked_operation_in_progress == true); 7642 /* Deletion failure */ 7643 CU_ASSERT(g_bserrno == -EBUSY); 7644 poll_threads(); 7645 CU_ASSERT(blob->locked_operation_in_progress == false); 7646 /* Snapshot creation success */ 7647 CU_ASSERT(g_bserrno == 0); 7648 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7649 7650 snapshotid = g_blobid; 7651 7652 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 7653 poll_threads(); 7654 CU_ASSERT(g_bserrno == 0); 7655 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7656 snapshot = g_blob; 7657 7658 /* Inflate blob and try to remove blob in the same time: 7659 * - blob should be inflated successfully 7660 * - delete operation should fail w -EBUSY */ 7661 CU_ASSERT(blob->locked_operation_in_progress == false); 7662 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 7663 CU_ASSERT(blob->locked_operation_in_progress == true); 7664 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7665 CU_ASSERT(blob->locked_operation_in_progress == true); 7666 /* Deletion failure */ 7667 CU_ASSERT(g_bserrno == -EBUSY); 7668 poll_threads(); 7669 CU_ASSERT(blob->locked_operation_in_progress == false); 7670 /* Inflation success */ 7671 CU_ASSERT(g_bserrno == 0); 7672 7673 /* Clone snapshot and try to remove snapshot in the same time: 7674 * - snapshot should be cloned successfully 7675 * - delete operation should fail w -EBUSY */ 7676 CU_ASSERT(blob->locked_operation_in_progress == false); 7677 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 7678 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 7679 /* Deletion failure */ 7680 CU_ASSERT(g_bserrno == -EBUSY); 7681 poll_threads(); 7682 CU_ASSERT(blob->locked_operation_in_progress == false); 7683 /* Clone created */ 7684 CU_ASSERT(g_bserrno == 0); 7685 7686 /* Resize blob and try to remove blob in the same time: 7687 * - blob should be resized successfully 7688 * - delete operation should fail w -EBUSY */ 7689 CU_ASSERT(blob->locked_operation_in_progress == false); 7690 spdk_blob_resize(blob, 50, blob_op_complete, NULL); 7691 CU_ASSERT(blob->locked_operation_in_progress == true); 7692 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7693 CU_ASSERT(blob->locked_operation_in_progress == true); 7694 /* Deletion failure */ 7695 CU_ASSERT(g_bserrno == -EBUSY); 7696 poll_threads(); 7697 CU_ASSERT(blob->locked_operation_in_progress == false); 7698 /* Blob resized successfully */ 7699 CU_ASSERT(g_bserrno == 0); 7700 7701 /* Issue two consecutive blob syncs, neither should fail. 7702 * Force sync to actually occur by marking blob dirty each time. 7703 * Execution of sync should not be enough to complete the operation, 7704 * since disk I/O is required to complete it. */ 7705 g_bserrno = -1; 7706 7707 blob->state = SPDK_BLOB_STATE_DIRTY; 7708 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7709 SPDK_CU_ASSERT_FATAL(g_bserrno == -1); 7710 7711 blob->state = SPDK_BLOB_STATE_DIRTY; 7712 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7713 SPDK_CU_ASSERT_FATAL(g_bserrno == -1); 7714 7715 uint32_t completions = 0; 7716 while (completions < 2) { 7717 SPDK_CU_ASSERT_FATAL(poll_thread_times(0, 1)); 7718 if (g_bserrno == 0) { 7719 g_bserrno = -1; 7720 completions++; 7721 } 7722 /* Never should the g_bserrno be other than -1. 7723 * It would mean that either of syncs failed. */ 7724 SPDK_CU_ASSERT_FATAL(g_bserrno == -1); 7725 } 7726 7727 spdk_blob_close(blob, blob_op_complete, NULL); 7728 poll_threads(); 7729 CU_ASSERT(g_bserrno == 0); 7730 7731 spdk_blob_close(snapshot, blob_op_complete, NULL); 7732 poll_threads(); 7733 CU_ASSERT(g_bserrno == 0); 7734 7735 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7736 poll_threads(); 7737 CU_ASSERT(g_bserrno == 0); 7738 7739 spdk_bs_unload(bs, bs_op_complete, NULL); 7740 poll_threads(); 7741 CU_ASSERT(g_bserrno == 0); 7742 g_bs = NULL; 7743 7744 spdk_bs_free_io_channel(channel); 7745 poll_threads(); 7746 } 7747 7748 static void 7749 blob_persist(void) 7750 { 7751 struct spdk_blob_store *bs; 7752 struct spdk_bs_dev *dev; 7753 struct spdk_blob_opts opts; 7754 struct spdk_blob *blob; 7755 spdk_blob_id blobid; 7756 struct spdk_io_channel *channel; 7757 char *xattr; 7758 size_t xattr_length; 7759 int rc; 7760 uint32_t page_count_clear, page_count_xattr; 7761 uint64_t poller_iterations; 7762 bool run_poller; 7763 7764 dev = init_dev(); 7765 7766 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 7767 poll_threads(); 7768 CU_ASSERT(g_bserrno == 0); 7769 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7770 bs = g_bs; 7771 7772 channel = spdk_bs_alloc_io_channel(bs); 7773 SPDK_CU_ASSERT_FATAL(channel != NULL); 7774 7775 ut_spdk_blob_opts_init(&opts); 7776 opts.num_clusters = 10; 7777 7778 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 7779 poll_threads(); 7780 CU_ASSERT(g_bserrno == 0); 7781 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7782 blobid = g_blobid; 7783 7784 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7785 poll_threads(); 7786 CU_ASSERT(g_bserrno == 0); 7787 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7788 blob = g_blob; 7789 7790 /* Save the amount of md pages used after creation of a blob. 7791 * This should be consistent after removing xattr. */ 7792 page_count_clear = spdk_bit_array_count_set(bs->used_md_pages); 7793 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_clear); 7794 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_clear); 7795 7796 /* Add xattr with maximum length of descriptor to exceed single metadata page. */ 7797 xattr_length = SPDK_BS_MAX_DESC_SIZE - sizeof(struct spdk_blob_md_descriptor_xattr) - 7798 strlen("large_xattr"); 7799 xattr = calloc(xattr_length, sizeof(char)); 7800 SPDK_CU_ASSERT_FATAL(xattr != NULL); 7801 7802 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); 7803 SPDK_CU_ASSERT_FATAL(rc == 0); 7804 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7805 poll_threads(); 7806 SPDK_CU_ASSERT_FATAL(g_bserrno == 0); 7807 7808 /* Save the amount of md pages used after adding the large xattr */ 7809 page_count_xattr = spdk_bit_array_count_set(bs->used_md_pages); 7810 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_xattr); 7811 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_xattr); 7812 7813 /* Add xattr to a blob and sync it. While sync is occuring, remove the xattr and sync again. 7814 * Interrupt the first sync after increasing number of poller iterations, until it succeeds. 7815 * Expectation is that after second sync completes no xattr is saved in metadata. */ 7816 poller_iterations = 1; 7817 run_poller = true; 7818 while (run_poller) { 7819 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); 7820 SPDK_CU_ASSERT_FATAL(rc == 0); 7821 g_bserrno = -1; 7822 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7823 poll_thread_times(0, poller_iterations); 7824 if (g_bserrno == 0) { 7825 /* Poller iteration count was high enough for first sync to complete. 7826 * Verify that blob takes up enough of md_pages to store the xattr. */ 7827 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_xattr); 7828 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_xattr); 7829 SPDK_CU_ASSERT_FATAL(spdk_bit_array_count_set(bs->used_md_pages) == page_count_xattr); 7830 run_poller = false; 7831 } 7832 rc = spdk_blob_remove_xattr(blob, "large_xattr"); 7833 SPDK_CU_ASSERT_FATAL(rc == 0); 7834 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7835 poll_threads(); 7836 SPDK_CU_ASSERT_FATAL(g_bserrno == 0); 7837 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_clear); 7838 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_clear); 7839 SPDK_CU_ASSERT_FATAL(spdk_bit_array_count_set(bs->used_md_pages) == page_count_clear); 7840 poller_iterations++; 7841 /* Stop at high iteration count to prevent infinite loop. 7842 * This value should be enough for first md sync to complete in any case. */ 7843 SPDK_CU_ASSERT_FATAL(poller_iterations < 50); 7844 } 7845 7846 free(xattr); 7847 7848 spdk_blob_close(blob, blob_op_complete, NULL); 7849 poll_threads(); 7850 CU_ASSERT(g_bserrno == 0); 7851 7852 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7853 poll_threads(); 7854 CU_ASSERT(g_bserrno == 0); 7855 7856 spdk_bs_unload(bs, bs_op_complete, NULL); 7857 poll_threads(); 7858 CU_ASSERT(g_bserrno == 0); 7859 g_bs = NULL; 7860 7861 spdk_bs_free_io_channel(channel); 7862 poll_threads(); 7863 } 7864 7865 int main(int argc, char **argv) 7866 { 7867 CU_pSuite suite = NULL; 7868 unsigned int num_failures; 7869 7870 CU_set_error_action(CUEA_ABORT); 7871 CU_initialize_registry(); 7872 7873 suite = CU_add_suite("blob", NULL, NULL); 7874 7875 CU_ADD_TEST(suite, blob_init); 7876 CU_ADD_TEST(suite, blob_open); 7877 CU_ADD_TEST(suite, blob_create); 7878 CU_ADD_TEST(suite, blob_create_internal); 7879 CU_ADD_TEST(suite, blob_thin_provision); 7880 CU_ADD_TEST(suite, blob_snapshot); 7881 CU_ADD_TEST(suite, blob_clone); 7882 CU_ADD_TEST(suite, blob_inflate); 7883 CU_ADD_TEST(suite, blob_delete); 7884 CU_ADD_TEST(suite, blob_resize); 7885 CU_ADD_TEST(suite, blob_read_only); 7886 CU_ADD_TEST(suite, channel_ops); 7887 CU_ADD_TEST(suite, blob_super); 7888 CU_ADD_TEST(suite, blob_write); 7889 CU_ADD_TEST(suite, blob_read); 7890 CU_ADD_TEST(suite, blob_rw_verify); 7891 CU_ADD_TEST(suite, blob_rw_verify_iov); 7892 CU_ADD_TEST(suite, blob_rw_verify_iov_nomem); 7893 CU_ADD_TEST(suite, blob_rw_iov_read_only); 7894 CU_ADD_TEST(suite, blob_unmap); 7895 CU_ADD_TEST(suite, blob_iter); 7896 CU_ADD_TEST(suite, blob_xattr); 7897 CU_ADD_TEST(suite, bs_load); 7898 CU_ADD_TEST(suite, bs_load_pending_removal); 7899 CU_ADD_TEST(suite, bs_load_custom_cluster_size); 7900 CU_ADD_TEST(suite, bs_unload); 7901 CU_ADD_TEST(suite, bs_cluster_sz); 7902 CU_ADD_TEST(suite, bs_usable_clusters); 7903 CU_ADD_TEST(suite, bs_resize_md); 7904 CU_ADD_TEST(suite, bs_destroy); 7905 CU_ADD_TEST(suite, bs_type); 7906 CU_ADD_TEST(suite, bs_super_block); 7907 CU_ADD_TEST(suite, blob_serialize); 7908 CU_ADD_TEST(suite, blob_crc); 7909 CU_ADD_TEST(suite, super_block_crc); 7910 CU_ADD_TEST(suite, blob_dirty_shutdown); 7911 CU_ADD_TEST(suite, blob_flags); 7912 CU_ADD_TEST(suite, bs_version); 7913 CU_ADD_TEST(suite, blob_set_xattrs); 7914 CU_ADD_TEST(suite, blob_thin_prov_alloc); 7915 CU_ADD_TEST(suite, blob_insert_cluster_msg); 7916 CU_ADD_TEST(suite, blob_thin_prov_rw); 7917 CU_ADD_TEST(suite, blob_thin_prov_rle); 7918 CU_ADD_TEST(suite, blob_thin_prov_rw_iov); 7919 CU_ADD_TEST(suite, bs_load_iter); 7920 CU_ADD_TEST(suite, blob_snapshot_rw); 7921 CU_ADD_TEST(suite, blob_snapshot_rw_iov); 7922 CU_ADD_TEST(suite, blob_relations); 7923 CU_ADD_TEST(suite, blob_relations2); 7924 CU_ADD_TEST(suite, blob_delete_snapshot_power_failure); 7925 CU_ADD_TEST(suite, blob_create_snapshot_power_failure); 7926 CU_ADD_TEST(suite, blob_inflate_rw); 7927 CU_ADD_TEST(suite, blob_snapshot_freeze_io); 7928 CU_ADD_TEST(suite, blob_operation_split_rw); 7929 CU_ADD_TEST(suite, blob_operation_split_rw_iov); 7930 CU_ADD_TEST(suite, blob_io_unit); 7931 CU_ADD_TEST(suite, blob_io_unit_compatiblity); 7932 CU_ADD_TEST(suite, blob_simultaneous_operations); 7933 CU_ADD_TEST(suite, blob_persist); 7934 7935 allocate_threads(2); 7936 set_thread(0); 7937 7938 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 7939 7940 CU_basic_set_mode(CU_BRM_VERBOSE); 7941 g_use_extent_table = false; 7942 CU_basic_run_tests(); 7943 num_failures = CU_get_number_of_failures(); 7944 g_use_extent_table = true; 7945 CU_basic_run_tests(); 7946 num_failures += CU_get_number_of_failures(); 7947 CU_cleanup_registry(); 7948 7949 free(g_dev_buffer); 7950 7951 free_threads(); 7952 7953 return num_failures; 7954 } 7955