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