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