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_blob_opts blob_opts; 3287 uint32_t clusters; 3288 int i; 3289 3290 /* Init blobstore */ 3291 dev = init_dev(); 3292 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3293 poll_threads(); 3294 CU_ASSERT(g_bserrno == 0); 3295 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3296 bs = g_bs; 3297 3298 clusters = spdk_bs_total_data_cluster_count(bs); 3299 3300 ut_bs_reload(&bs, NULL); 3301 3302 CU_ASSERT(spdk_bs_total_data_cluster_count(bs) == clusters); 3303 ut_spdk_blob_opts_init(&blob_opts); 3304 3305 /* Create and resize blobs to make sure that useable cluster count won't change */ 3306 for (i = 0; i < 4; i++) { 3307 g_bserrno = -1; 3308 g_blobid = SPDK_BLOBID_INVALID; 3309 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3310 poll_threads(); 3311 CU_ASSERT(g_bserrno == 0); 3312 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3313 3314 g_bserrno = -1; 3315 g_blob = NULL; 3316 spdk_bs_open_blob(bs, g_blobid, blob_op_with_handle_complete, NULL); 3317 poll_threads(); 3318 CU_ASSERT(g_bserrno == 0); 3319 CU_ASSERT(g_blob != NULL); 3320 3321 spdk_blob_resize(g_blob, 10, blob_op_complete, NULL); 3322 poll_threads(); 3323 CU_ASSERT(g_bserrno == 0); 3324 3325 g_bserrno = -1; 3326 spdk_blob_close(g_blob, blob_op_complete, NULL); 3327 poll_threads(); 3328 CU_ASSERT(g_bserrno == 0); 3329 3330 CU_ASSERT(spdk_bs_total_data_cluster_count(bs) == clusters); 3331 } 3332 3333 /* Reload the blob store to make sure that nothing changed */ 3334 ut_bs_reload(&bs, NULL); 3335 3336 CU_ASSERT(spdk_bs_total_data_cluster_count(bs) == clusters); 3337 3338 spdk_bs_unload(bs, bs_op_complete, NULL); 3339 poll_threads(); 3340 CU_ASSERT(g_bserrno == 0); 3341 g_bs = NULL; 3342 } 3343 3344 /* 3345 * Test resizing of the metadata blob. This requires creating enough blobs 3346 * so that one cluster is not enough to fit the metadata for those blobs. 3347 * To induce this condition to happen more quickly, we reduce the cluster 3348 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 3349 */ 3350 static void 3351 bs_resize_md(void) 3352 { 3353 struct spdk_blob_store *bs; 3354 const int CLUSTER_PAGE_COUNT = 4; 3355 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 3356 struct spdk_bs_dev *dev; 3357 struct spdk_bs_opts opts; 3358 struct spdk_blob_opts blob_opts; 3359 uint32_t cluster_sz; 3360 spdk_blob_id blobids[NUM_BLOBS]; 3361 int i; 3362 3363 3364 dev = init_dev(); 3365 spdk_bs_opts_init(&opts); 3366 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 3367 cluster_sz = opts.cluster_sz; 3368 3369 /* Initialize a new blob store */ 3370 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3371 poll_threads(); 3372 CU_ASSERT(g_bserrno == 0); 3373 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3374 bs = g_bs; 3375 3376 CU_ASSERT(spdk_bs_get_cluster_size(bs) == cluster_sz); 3377 3378 ut_spdk_blob_opts_init(&blob_opts); 3379 3380 for (i = 0; i < NUM_BLOBS; i++) { 3381 g_bserrno = -1; 3382 g_blobid = SPDK_BLOBID_INVALID; 3383 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3384 poll_threads(); 3385 CU_ASSERT(g_bserrno == 0); 3386 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3387 blobids[i] = g_blobid; 3388 } 3389 3390 ut_bs_reload(&bs, &opts); 3391 3392 CU_ASSERT(spdk_bs_get_cluster_size(bs) == cluster_sz); 3393 3394 for (i = 0; i < NUM_BLOBS; i++) { 3395 g_bserrno = -1; 3396 g_blob = NULL; 3397 spdk_bs_open_blob(bs, blobids[i], blob_op_with_handle_complete, NULL); 3398 poll_threads(); 3399 CU_ASSERT(g_bserrno == 0); 3400 CU_ASSERT(g_blob != NULL); 3401 g_bserrno = -1; 3402 spdk_blob_close(g_blob, blob_op_complete, NULL); 3403 poll_threads(); 3404 CU_ASSERT(g_bserrno == 0); 3405 } 3406 3407 spdk_bs_unload(bs, bs_op_complete, NULL); 3408 poll_threads(); 3409 CU_ASSERT(g_bserrno == 0); 3410 g_bs = NULL; 3411 } 3412 3413 static void 3414 bs_destroy(void) 3415 { 3416 struct spdk_blob_store *bs; 3417 struct spdk_bs_dev *dev; 3418 3419 /* Initialize a new blob store */ 3420 dev = init_dev(); 3421 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3422 poll_threads(); 3423 CU_ASSERT(g_bserrno == 0); 3424 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3425 bs = g_bs; 3426 3427 /* Destroy the blob store */ 3428 g_bserrno = -1; 3429 spdk_bs_destroy(bs, bs_op_complete, NULL); 3430 poll_threads(); 3431 CU_ASSERT(g_bserrno == 0); 3432 3433 /* Loading an non-existent blob store should fail. */ 3434 g_bs = NULL; 3435 dev = init_dev(); 3436 3437 g_bserrno = 0; 3438 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3439 poll_threads(); 3440 CU_ASSERT(g_bserrno != 0); 3441 } 3442 3443 /* Try to hit all of the corner cases associated with serializing 3444 * a blob to disk 3445 */ 3446 static void 3447 blob_serialize(void) 3448 { 3449 struct spdk_bs_dev *dev; 3450 struct spdk_bs_opts opts; 3451 struct spdk_blob_store *bs; 3452 struct spdk_blob_opts blob_opts; 3453 spdk_blob_id blobid[2]; 3454 struct spdk_blob *blob[2]; 3455 uint64_t i; 3456 char *value; 3457 int rc; 3458 3459 dev = init_dev(); 3460 3461 /* Initialize a new blobstore with very small clusters */ 3462 spdk_bs_opts_init(&opts); 3463 opts.cluster_sz = dev->blocklen * 8; 3464 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3465 poll_threads(); 3466 CU_ASSERT(g_bserrno == 0); 3467 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3468 bs = g_bs; 3469 ut_spdk_blob_opts_init(&blob_opts); 3470 3471 /* Create and open two blobs */ 3472 for (i = 0; i < 2; i++) { 3473 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3474 poll_threads(); 3475 CU_ASSERT(g_bserrno == 0); 3476 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3477 blobid[i] = g_blobid; 3478 3479 /* Open a blob */ 3480 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 3481 poll_threads(); 3482 CU_ASSERT(g_bserrno == 0); 3483 CU_ASSERT(g_blob != NULL); 3484 blob[i] = g_blob; 3485 3486 /* Set a fairly large xattr on both blobs to eat up 3487 * metadata space 3488 */ 3489 value = calloc(dev->blocklen - 64, sizeof(char)); 3490 SPDK_CU_ASSERT_FATAL(value != NULL); 3491 memset(value, i, dev->blocklen / 2); 3492 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 3493 CU_ASSERT(rc == 0); 3494 free(value); 3495 } 3496 3497 /* Resize the blobs, alternating 1 cluster at a time. 3498 * This thwarts run length encoding and will cause spill 3499 * over of the extents. 3500 */ 3501 for (i = 0; i < 6; i++) { 3502 spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL); 3503 poll_threads(); 3504 CU_ASSERT(g_bserrno == 0); 3505 } 3506 3507 for (i = 0; i < 2; i++) { 3508 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 3509 poll_threads(); 3510 CU_ASSERT(g_bserrno == 0); 3511 } 3512 3513 /* Close the blobs */ 3514 for (i = 0; i < 2; i++) { 3515 spdk_blob_close(blob[i], blob_op_complete, NULL); 3516 poll_threads(); 3517 CU_ASSERT(g_bserrno == 0); 3518 } 3519 3520 ut_bs_reload(&bs, &opts); 3521 3522 for (i = 0; i < 2; i++) { 3523 blob[i] = NULL; 3524 3525 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 3526 poll_threads(); 3527 CU_ASSERT(g_bserrno == 0); 3528 CU_ASSERT(g_blob != NULL); 3529 blob[i] = g_blob; 3530 3531 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 3532 3533 spdk_blob_close(blob[i], blob_op_complete, NULL); 3534 poll_threads(); 3535 CU_ASSERT(g_bserrno == 0); 3536 } 3537 3538 spdk_bs_unload(bs, bs_op_complete, NULL); 3539 poll_threads(); 3540 CU_ASSERT(g_bserrno == 0); 3541 g_bs = NULL; 3542 } 3543 3544 static void 3545 blob_crc(void) 3546 { 3547 struct spdk_blob_store *bs; 3548 struct spdk_bs_dev *dev; 3549 struct spdk_blob *blob; 3550 spdk_blob_id blobid; 3551 uint32_t page_num; 3552 int index; 3553 struct spdk_blob_md_page *page; 3554 struct spdk_blob_opts blob_opts; 3555 3556 dev = init_dev(); 3557 3558 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3559 poll_threads(); 3560 CU_ASSERT(g_bserrno == 0); 3561 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3562 bs = g_bs; 3563 3564 ut_spdk_blob_opts_init(&blob_opts); 3565 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3566 poll_threads(); 3567 CU_ASSERT(g_bserrno == 0); 3568 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3569 blobid = g_blobid; 3570 3571 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3572 poll_threads(); 3573 CU_ASSERT(g_bserrno == 0); 3574 CU_ASSERT(g_blob != NULL); 3575 blob = g_blob; 3576 3577 spdk_blob_close(blob, blob_op_complete, NULL); 3578 poll_threads(); 3579 CU_ASSERT(g_bserrno == 0); 3580 3581 page_num = _spdk_bs_blobid_to_page(blobid); 3582 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 3583 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3584 page->crc = 0; 3585 3586 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3587 poll_threads(); 3588 CU_ASSERT(g_bserrno == -EINVAL); 3589 CU_ASSERT(g_blob == NULL); 3590 g_bserrno = 0; 3591 3592 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3593 poll_threads(); 3594 CU_ASSERT(g_bserrno == -EINVAL); 3595 3596 spdk_bs_unload(bs, bs_op_complete, NULL); 3597 poll_threads(); 3598 CU_ASSERT(g_bserrno == 0); 3599 g_bs = NULL; 3600 } 3601 3602 static void 3603 super_block_crc(void) 3604 { 3605 struct spdk_blob_store *bs; 3606 struct spdk_bs_dev *dev; 3607 struct spdk_bs_super_block *super_block; 3608 3609 dev = init_dev(); 3610 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3611 poll_threads(); 3612 CU_ASSERT(g_bserrno == 0); 3613 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3614 bs = g_bs; 3615 3616 spdk_bs_unload(bs, bs_op_complete, NULL); 3617 poll_threads(); 3618 CU_ASSERT(g_bserrno == 0); 3619 g_bs = NULL; 3620 3621 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 3622 super_block->crc = 0; 3623 dev = init_dev(); 3624 3625 /* Load an existing blob store */ 3626 g_bserrno = 0; 3627 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3628 poll_threads(); 3629 CU_ASSERT(g_bserrno == -EILSEQ); 3630 } 3631 3632 /* For blob dirty shutdown test case we do the following sub-test cases: 3633 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we 3634 * dirty shutdown and reload the blob store and verify the xattrs. 3635 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 3636 * reload the blob store and verify the clusters number. 3637 * 3 Create the second blob and then dirty shutdown, reload the blob store 3638 * and verify the second blob. 3639 * 4 Delete the second blob and then dirty shutdown, reload the blob store 3640 * and verify the second blob is invalid. 3641 * 5 Create the second blob again and also create the third blob, modify the 3642 * md of second blob which makes the md invalid, and then dirty shutdown, 3643 * reload the blob store verify the second blob, it should invalid and also 3644 * verify the third blob, it should correct. 3645 */ 3646 static void 3647 blob_dirty_shutdown(void) 3648 { 3649 int rc; 3650 int index; 3651 struct spdk_blob_store *bs; 3652 struct spdk_bs_dev *dev; 3653 spdk_blob_id blobid1, blobid2, blobid3; 3654 struct spdk_blob *blob; 3655 uint64_t length; 3656 uint64_t free_clusters; 3657 const void *value; 3658 size_t value_len; 3659 uint32_t page_num; 3660 struct spdk_blob_md_page *page; 3661 struct spdk_blob_opts blob_opts; 3662 3663 dev = init_dev(); 3664 /* Initialize a new blob store */ 3665 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3666 poll_threads(); 3667 CU_ASSERT(g_bserrno == 0); 3668 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3669 bs = g_bs; 3670 3671 /* Create first blob */ 3672 ut_spdk_blob_opts_init(&blob_opts); 3673 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3674 poll_threads(); 3675 CU_ASSERT(g_bserrno == 0); 3676 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3677 blobid1 = g_blobid; 3678 3679 spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL); 3680 poll_threads(); 3681 CU_ASSERT(g_bserrno == 0); 3682 CU_ASSERT(g_blob != NULL); 3683 blob = g_blob; 3684 3685 /* Set some xattrs */ 3686 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 3687 CU_ASSERT(rc == 0); 3688 3689 length = 2345; 3690 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3691 CU_ASSERT(rc == 0); 3692 3693 /* Put xattr that fits exactly single page. 3694 * This results in adding additional pages to MD. 3695 * First is flags and smaller xattr, second the large xattr, 3696 * third are just the extents. 3697 */ 3698 size_t xattr_length = 4072 - sizeof(struct spdk_blob_md_descriptor_xattr) - 3699 strlen("large_xattr"); 3700 char *xattr = calloc(xattr_length, sizeof(char)); 3701 SPDK_CU_ASSERT_FATAL(xattr != NULL); 3702 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); 3703 free(xattr); 3704 SPDK_CU_ASSERT_FATAL(rc == 0); 3705 3706 /* Resize the blob */ 3707 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3708 poll_threads(); 3709 CU_ASSERT(g_bserrno == 0); 3710 3711 /* Set the blob as the super blob */ 3712 spdk_bs_set_super(bs, blobid1, blob_op_complete, NULL); 3713 poll_threads(); 3714 CU_ASSERT(g_bserrno == 0); 3715 3716 free_clusters = spdk_bs_free_cluster_count(bs); 3717 3718 spdk_blob_close(blob, blob_op_complete, NULL); 3719 poll_threads(); 3720 CU_ASSERT(g_bserrno == 0); 3721 blob = NULL; 3722 g_blob = NULL; 3723 g_blobid = SPDK_BLOBID_INVALID; 3724 3725 ut_bs_dirty_load(&bs, NULL); 3726 3727 /* Get the super blob */ 3728 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 3729 poll_threads(); 3730 CU_ASSERT(g_bserrno == 0); 3731 CU_ASSERT(blobid1 == g_blobid); 3732 3733 spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL); 3734 poll_threads(); 3735 CU_ASSERT(g_bserrno == 0); 3736 CU_ASSERT(g_blob != NULL); 3737 blob = g_blob; 3738 3739 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3740 3741 /* Get the xattrs */ 3742 value = NULL; 3743 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3744 CU_ASSERT(rc == 0); 3745 SPDK_CU_ASSERT_FATAL(value != NULL); 3746 CU_ASSERT(*(uint64_t *)value == length); 3747 CU_ASSERT(value_len == 8); 3748 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3749 3750 /* Resize the blob */ 3751 spdk_blob_resize(blob, 20, blob_op_complete, NULL); 3752 poll_threads(); 3753 CU_ASSERT(g_bserrno == 0); 3754 3755 free_clusters = spdk_bs_free_cluster_count(bs); 3756 3757 spdk_blob_close(blob, blob_op_complete, NULL); 3758 poll_threads(); 3759 CU_ASSERT(g_bserrno == 0); 3760 blob = NULL; 3761 g_blob = NULL; 3762 g_blobid = SPDK_BLOBID_INVALID; 3763 3764 ut_bs_dirty_load(&bs, NULL); 3765 3766 spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL); 3767 poll_threads(); 3768 CU_ASSERT(g_bserrno == 0); 3769 CU_ASSERT(g_blob != NULL); 3770 blob = g_blob; 3771 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 3772 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3773 3774 spdk_blob_close(blob, blob_op_complete, NULL); 3775 poll_threads(); 3776 CU_ASSERT(g_bserrno == 0); 3777 blob = NULL; 3778 g_blob = NULL; 3779 g_blobid = SPDK_BLOBID_INVALID; 3780 3781 /* Create second blob */ 3782 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3783 poll_threads(); 3784 CU_ASSERT(g_bserrno == 0); 3785 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3786 blobid2 = g_blobid; 3787 3788 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 3789 poll_threads(); 3790 CU_ASSERT(g_bserrno == 0); 3791 CU_ASSERT(g_blob != NULL); 3792 blob = g_blob; 3793 3794 /* Set some xattrs */ 3795 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3796 CU_ASSERT(rc == 0); 3797 3798 length = 5432; 3799 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3800 CU_ASSERT(rc == 0); 3801 3802 /* Resize the blob */ 3803 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3804 poll_threads(); 3805 CU_ASSERT(g_bserrno == 0); 3806 3807 free_clusters = spdk_bs_free_cluster_count(bs); 3808 3809 spdk_blob_close(blob, blob_op_complete, NULL); 3810 poll_threads(); 3811 CU_ASSERT(g_bserrno == 0); 3812 blob = NULL; 3813 g_blob = NULL; 3814 g_blobid = SPDK_BLOBID_INVALID; 3815 3816 ut_bs_dirty_load(&bs, NULL); 3817 3818 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 3819 poll_threads(); 3820 CU_ASSERT(g_bserrno == 0); 3821 CU_ASSERT(g_blob != NULL); 3822 blob = g_blob; 3823 3824 /* Get the xattrs */ 3825 value = NULL; 3826 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3827 CU_ASSERT(rc == 0); 3828 SPDK_CU_ASSERT_FATAL(value != NULL); 3829 CU_ASSERT(*(uint64_t *)value == length); 3830 CU_ASSERT(value_len == 8); 3831 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3832 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3833 3834 spdk_blob_close(blob, blob_op_complete, NULL); 3835 poll_threads(); 3836 CU_ASSERT(g_bserrno == 0); 3837 spdk_bs_delete_blob(bs, blobid2, blob_op_complete, NULL); 3838 poll_threads(); 3839 CU_ASSERT(g_bserrno == 0); 3840 3841 free_clusters = spdk_bs_free_cluster_count(bs); 3842 3843 ut_bs_dirty_load(&bs, NULL); 3844 3845 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 3846 poll_threads(); 3847 CU_ASSERT(g_bserrno != 0); 3848 CU_ASSERT(g_blob == NULL); 3849 3850 spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL); 3851 poll_threads(); 3852 CU_ASSERT(g_bserrno == 0); 3853 CU_ASSERT(g_blob != NULL); 3854 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3855 spdk_blob_close(g_blob, blob_op_complete, NULL); 3856 poll_threads(); 3857 CU_ASSERT(g_bserrno == 0); 3858 3859 ut_bs_reload(&bs, NULL); 3860 3861 /* Create second blob */ 3862 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3863 poll_threads(); 3864 CU_ASSERT(g_bserrno == 0); 3865 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3866 blobid2 = g_blobid; 3867 3868 /* Create third blob */ 3869 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3870 poll_threads(); 3871 CU_ASSERT(g_bserrno == 0); 3872 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3873 blobid3 = g_blobid; 3874 3875 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 3876 poll_threads(); 3877 CU_ASSERT(g_bserrno == 0); 3878 CU_ASSERT(g_blob != NULL); 3879 blob = g_blob; 3880 3881 /* Set some xattrs for second blob */ 3882 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3883 CU_ASSERT(rc == 0); 3884 3885 length = 5432; 3886 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3887 CU_ASSERT(rc == 0); 3888 3889 spdk_blob_close(blob, blob_op_complete, NULL); 3890 poll_threads(); 3891 CU_ASSERT(g_bserrno == 0); 3892 blob = NULL; 3893 g_blob = NULL; 3894 g_blobid = SPDK_BLOBID_INVALID; 3895 3896 spdk_bs_open_blob(bs, blobid3, blob_op_with_handle_complete, NULL); 3897 poll_threads(); 3898 CU_ASSERT(g_bserrno == 0); 3899 CU_ASSERT(g_blob != NULL); 3900 blob = g_blob; 3901 3902 /* Set some xattrs for third blob */ 3903 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 3904 CU_ASSERT(rc == 0); 3905 3906 length = 5432; 3907 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3908 CU_ASSERT(rc == 0); 3909 3910 spdk_blob_close(blob, blob_op_complete, NULL); 3911 poll_threads(); 3912 CU_ASSERT(g_bserrno == 0); 3913 blob = NULL; 3914 g_blob = NULL; 3915 g_blobid = SPDK_BLOBID_INVALID; 3916 3917 /* Mark second blob as invalid */ 3918 page_num = _spdk_bs_blobid_to_page(blobid2); 3919 3920 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 3921 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3922 page->sequence_num = 1; 3923 page->crc = _spdk_blob_md_page_calc_crc(page); 3924 3925 free_clusters = spdk_bs_free_cluster_count(bs); 3926 3927 ut_bs_dirty_load(&bs, NULL); 3928 3929 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 3930 poll_threads(); 3931 CU_ASSERT(g_bserrno != 0); 3932 CU_ASSERT(g_blob == NULL); 3933 3934 spdk_bs_open_blob(bs, blobid3, blob_op_with_handle_complete, NULL); 3935 poll_threads(); 3936 CU_ASSERT(g_bserrno == 0); 3937 CU_ASSERT(g_blob != NULL); 3938 blob = g_blob; 3939 3940 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3941 3942 spdk_blob_close(blob, blob_op_complete, NULL); 3943 poll_threads(); 3944 CU_ASSERT(g_bserrno == 0); 3945 blob = NULL; 3946 g_blob = NULL; 3947 g_blobid = SPDK_BLOBID_INVALID; 3948 3949 spdk_bs_unload(bs, bs_op_complete, NULL); 3950 poll_threads(); 3951 CU_ASSERT(g_bserrno == 0); 3952 g_bs = NULL; 3953 } 3954 3955 static void 3956 blob_flags(void) 3957 { 3958 struct spdk_blob_store *bs; 3959 struct spdk_bs_dev *dev; 3960 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 3961 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 3962 struct spdk_blob_opts blob_opts; 3963 int rc; 3964 3965 dev = init_dev(); 3966 ut_spdk_blob_opts_init(&blob_opts); 3967 3968 /* Initialize a new blob store */ 3969 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3970 poll_threads(); 3971 CU_ASSERT(g_bserrno == 0); 3972 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3973 bs = g_bs; 3974 3975 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 3976 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3977 poll_threads(); 3978 CU_ASSERT(g_bserrno == 0); 3979 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3980 blobid_invalid = g_blobid; 3981 3982 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3983 poll_threads(); 3984 CU_ASSERT(g_bserrno == 0); 3985 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3986 blobid_data_ro = g_blobid; 3987 3988 blob_opts.clear_method = BLOB_CLEAR_WITH_WRITE_ZEROES; 3989 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3990 poll_threads(); 3991 CU_ASSERT(g_bserrno == 0); 3992 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3993 blobid_md_ro = g_blobid; 3994 3995 spdk_bs_open_blob(bs, blobid_invalid, blob_op_with_handle_complete, NULL); 3996 poll_threads(); 3997 CU_ASSERT(g_bserrno == 0); 3998 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3999 blob_invalid = g_blob; 4000 4001 spdk_bs_open_blob(bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 4002 poll_threads(); 4003 CU_ASSERT(g_bserrno == 0); 4004 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4005 blob_data_ro = g_blob; 4006 4007 spdk_bs_open_blob(bs, blobid_md_ro, 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_md_ro = g_blob; 4012 CU_ASSERT((blob_md_ro->md_ro_flags & SPDK_BLOB_MD_RO_FLAGS_MASK) == BLOB_CLEAR_WITH_WRITE_ZEROES); 4013 4014 /* Change the size of blob_data_ro to check if flags are serialized 4015 * when blob has non zero number of extents */ 4016 spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL); 4017 poll_threads(); 4018 CU_ASSERT(g_bserrno == 0); 4019 4020 /* Set the xattr to check if flags are serialized 4021 * when blob has non zero number of xattrs */ 4022 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 4023 CU_ASSERT(rc == 0); 4024 4025 blob_invalid->invalid_flags = (1ULL << 63); 4026 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 4027 blob_data_ro->data_ro_flags = (1ULL << 62); 4028 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 4029 blob_md_ro->md_ro_flags = (1ULL << 61); 4030 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 4031 4032 g_bserrno = -1; 4033 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 4034 poll_threads(); 4035 CU_ASSERT(g_bserrno == 0); 4036 g_bserrno = -1; 4037 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 4038 poll_threads(); 4039 CU_ASSERT(g_bserrno == 0); 4040 g_bserrno = -1; 4041 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 4042 poll_threads(); 4043 CU_ASSERT(g_bserrno == 0); 4044 4045 g_bserrno = -1; 4046 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 4047 poll_threads(); 4048 CU_ASSERT(g_bserrno == 0); 4049 blob_invalid = NULL; 4050 g_bserrno = -1; 4051 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 4052 poll_threads(); 4053 CU_ASSERT(g_bserrno == 0); 4054 blob_data_ro = NULL; 4055 g_bserrno = -1; 4056 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 4057 poll_threads(); 4058 CU_ASSERT(g_bserrno == 0); 4059 blob_md_ro = NULL; 4060 4061 g_blob = NULL; 4062 g_blobid = SPDK_BLOBID_INVALID; 4063 4064 ut_bs_reload(&bs, NULL); 4065 4066 g_blob = NULL; 4067 g_bserrno = 0; 4068 spdk_bs_open_blob(bs, blobid_invalid, blob_op_with_handle_complete, NULL); 4069 poll_threads(); 4070 CU_ASSERT(g_bserrno != 0); 4071 CU_ASSERT(g_blob == NULL); 4072 4073 g_blob = NULL; 4074 g_bserrno = -1; 4075 spdk_bs_open_blob(bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 4076 poll_threads(); 4077 CU_ASSERT(g_bserrno == 0); 4078 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4079 blob_data_ro = g_blob; 4080 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 4081 CU_ASSERT(blob_data_ro->data_ro == true); 4082 CU_ASSERT(blob_data_ro->md_ro == true); 4083 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 4084 4085 g_blob = NULL; 4086 g_bserrno = -1; 4087 spdk_bs_open_blob(bs, blobid_md_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_md_ro = g_blob; 4092 CU_ASSERT(blob_md_ro->data_ro == false); 4093 CU_ASSERT(blob_md_ro->md_ro == true); 4094 4095 g_bserrno = -1; 4096 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 4097 poll_threads(); 4098 CU_ASSERT(g_bserrno == 0); 4099 4100 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 4101 poll_threads(); 4102 CU_ASSERT(g_bserrno == 0); 4103 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 4104 poll_threads(); 4105 CU_ASSERT(g_bserrno == 0); 4106 4107 spdk_bs_unload(bs, bs_op_complete, NULL); 4108 poll_threads(); 4109 CU_ASSERT(g_bserrno == 0); 4110 } 4111 4112 static void 4113 bs_version(void) 4114 { 4115 struct spdk_bs_super_block *super; 4116 struct spdk_blob_store *bs; 4117 struct spdk_bs_dev *dev; 4118 struct spdk_blob_opts blob_opts; 4119 spdk_blob_id blobid; 4120 4121 dev = init_dev(); 4122 4123 /* Initialize a new blob store */ 4124 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4125 poll_threads(); 4126 CU_ASSERT(g_bserrno == 0); 4127 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4128 bs = g_bs; 4129 4130 /* Unload the blob store */ 4131 spdk_bs_unload(bs, bs_op_complete, NULL); 4132 poll_threads(); 4133 CU_ASSERT(g_bserrno == 0); 4134 g_bs = NULL; 4135 4136 /* 4137 * Change the bs version on disk. This will allow us to 4138 * test that the version does not get modified automatically 4139 * when loading and unloading the blobstore. 4140 */ 4141 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 4142 CU_ASSERT(super->version == SPDK_BS_VERSION); 4143 CU_ASSERT(super->clean == 1); 4144 super->version = 2; 4145 /* 4146 * Version 2 metadata does not have a used blobid mask, so clear 4147 * those fields in the super block and zero the corresponding 4148 * region on "disk". We will use this to ensure blob IDs are 4149 * correctly reconstructed. 4150 */ 4151 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 4152 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 4153 super->used_blobid_mask_start = 0; 4154 super->used_blobid_mask_len = 0; 4155 super->crc = _spdk_blob_md_page_calc_crc(super); 4156 4157 /* Load an existing blob store */ 4158 dev = init_dev(); 4159 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4160 poll_threads(); 4161 CU_ASSERT(g_bserrno == 0); 4162 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4163 CU_ASSERT(super->clean == 1); 4164 bs = g_bs; 4165 4166 /* 4167 * Create a blob - just to make sure that when we unload it 4168 * results in writing the super block (since metadata pages 4169 * were allocated. 4170 */ 4171 ut_spdk_blob_opts_init(&blob_opts); 4172 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 4173 poll_threads(); 4174 CU_ASSERT(g_bserrno == 0); 4175 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4176 blobid = g_blobid; 4177 4178 /* Unload the blob store */ 4179 spdk_bs_unload(bs, bs_op_complete, NULL); 4180 poll_threads(); 4181 CU_ASSERT(g_bserrno == 0); 4182 g_bs = NULL; 4183 CU_ASSERT(super->version == 2); 4184 CU_ASSERT(super->used_blobid_mask_start == 0); 4185 CU_ASSERT(super->used_blobid_mask_len == 0); 4186 4187 dev = init_dev(); 4188 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4189 poll_threads(); 4190 CU_ASSERT(g_bserrno == 0); 4191 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4192 bs = g_bs; 4193 4194 g_blob = NULL; 4195 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4196 poll_threads(); 4197 CU_ASSERT(g_bserrno == 0); 4198 CU_ASSERT(g_blob != NULL); 4199 4200 spdk_blob_close(g_blob, blob_op_complete, NULL); 4201 poll_threads(); 4202 CU_ASSERT(g_bserrno == 0); 4203 4204 spdk_bs_unload(bs, bs_op_complete, NULL); 4205 poll_threads(); 4206 CU_ASSERT(g_bserrno == 0); 4207 g_bs = NULL; 4208 CU_ASSERT(super->version == 2); 4209 CU_ASSERT(super->used_blobid_mask_start == 0); 4210 CU_ASSERT(super->used_blobid_mask_len == 0); 4211 } 4212 4213 static void 4214 blob_set_xattrs(void) 4215 { 4216 struct spdk_blob_store *bs; 4217 struct spdk_bs_dev *dev; 4218 struct spdk_blob *blob; 4219 struct spdk_blob_opts opts; 4220 spdk_blob_id blobid; 4221 const void *value; 4222 size_t value_len; 4223 char *xattr; 4224 size_t xattr_length; 4225 int rc; 4226 4227 dev = init_dev(); 4228 4229 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4230 poll_threads(); 4231 CU_ASSERT(g_bserrno == 0); 4232 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4233 bs = g_bs; 4234 4235 /* Create blob with extra attributes */ 4236 ut_spdk_blob_opts_init(&opts); 4237 4238 opts.xattrs.names = g_xattr_names; 4239 opts.xattrs.get_value = _get_xattr_value; 4240 opts.xattrs.count = 3; 4241 opts.xattrs.ctx = &g_ctx; 4242 4243 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4244 poll_threads(); 4245 CU_ASSERT(g_bserrno == 0); 4246 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4247 blobid = g_blobid; 4248 4249 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4250 poll_threads(); 4251 CU_ASSERT(g_bserrno == 0); 4252 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4253 blob = g_blob; 4254 4255 /* Get the xattrs */ 4256 value = NULL; 4257 4258 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 4259 CU_ASSERT(rc == 0); 4260 SPDK_CU_ASSERT_FATAL(value != NULL); 4261 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 4262 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 4263 4264 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 4265 CU_ASSERT(rc == 0); 4266 SPDK_CU_ASSERT_FATAL(value != NULL); 4267 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 4268 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 4269 4270 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 4271 CU_ASSERT(rc == 0); 4272 SPDK_CU_ASSERT_FATAL(value != NULL); 4273 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 4274 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 4275 4276 /* Try to get non existing attribute */ 4277 4278 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 4279 CU_ASSERT(rc == -ENOENT); 4280 4281 /* Try xattr exceeding maximum length of descriptor in single page */ 4282 xattr_length = SPDK_BS_MAX_DESC_SIZE - sizeof(struct spdk_blob_md_descriptor_xattr) - 4283 strlen("large_xattr") + 1; 4284 xattr = calloc(xattr_length, sizeof(char)); 4285 SPDK_CU_ASSERT_FATAL(xattr != NULL); 4286 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); 4287 free(xattr); 4288 SPDK_CU_ASSERT_FATAL(rc == -ENOMEM); 4289 4290 spdk_blob_close(blob, blob_op_complete, NULL); 4291 poll_threads(); 4292 CU_ASSERT(g_bserrno == 0); 4293 blob = NULL; 4294 g_blob = NULL; 4295 g_blobid = SPDK_BLOBID_INVALID; 4296 4297 /* NULL callback */ 4298 ut_spdk_blob_opts_init(&opts); 4299 opts.xattrs.names = g_xattr_names; 4300 opts.xattrs.get_value = NULL; 4301 opts.xattrs.count = 1; 4302 opts.xattrs.ctx = &g_ctx; 4303 4304 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4305 poll_threads(); 4306 CU_ASSERT(g_bserrno == -EINVAL); 4307 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4308 4309 /* NULL values */ 4310 ut_spdk_blob_opts_init(&opts); 4311 opts.xattrs.names = g_xattr_names; 4312 opts.xattrs.get_value = _get_xattr_value_null; 4313 opts.xattrs.count = 1; 4314 opts.xattrs.ctx = NULL; 4315 4316 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4317 poll_threads(); 4318 CU_ASSERT(g_bserrno == -EINVAL); 4319 4320 spdk_bs_unload(bs, bs_op_complete, NULL); 4321 poll_threads(); 4322 CU_ASSERT(g_bserrno == 0); 4323 g_bs = NULL; 4324 4325 } 4326 4327 static void 4328 blob_thin_prov_alloc(void) 4329 { 4330 struct spdk_blob_store *bs; 4331 struct spdk_bs_dev *dev; 4332 struct spdk_blob *blob; 4333 struct spdk_blob_opts opts; 4334 spdk_blob_id blobid; 4335 uint64_t free_clusters; 4336 4337 dev = init_dev(); 4338 4339 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4340 poll_threads(); 4341 CU_ASSERT(g_bserrno == 0); 4342 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4343 bs = g_bs; 4344 free_clusters = spdk_bs_free_cluster_count(bs); 4345 4346 /* Set blob as thin provisioned */ 4347 ut_spdk_blob_opts_init(&opts); 4348 opts.thin_provision = true; 4349 4350 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4351 poll_threads(); 4352 CU_ASSERT(g_bserrno == 0); 4353 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4354 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4355 blobid = g_blobid; 4356 4357 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4358 poll_threads(); 4359 CU_ASSERT(g_bserrno == 0); 4360 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4361 blob = g_blob; 4362 4363 CU_ASSERT(blob->active.num_clusters == 0); 4364 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 4365 4366 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4367 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4368 poll_threads(); 4369 CU_ASSERT(g_bserrno == 0); 4370 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4371 CU_ASSERT(blob->active.num_clusters == 5); 4372 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4373 4374 /* Grow it to 1TB - still unallocated */ 4375 spdk_blob_resize(blob, 262144, blob_op_complete, NULL); 4376 poll_threads(); 4377 CU_ASSERT(g_bserrno == 0); 4378 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4379 CU_ASSERT(blob->active.num_clusters == 262144); 4380 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 4381 4382 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4383 poll_threads(); 4384 CU_ASSERT(g_bserrno == 0); 4385 /* Sync must not change anything */ 4386 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4387 CU_ASSERT(blob->active.num_clusters == 262144); 4388 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 4389 /* Since clusters are not allocated, 4390 * number of metadata pages is expected to be minimal. 4391 */ 4392 CU_ASSERT(blob->active.num_pages == 1); 4393 4394 /* Shrink the blob to 3 clusters - still unallocated */ 4395 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 4396 poll_threads(); 4397 CU_ASSERT(g_bserrno == 0); 4398 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4399 CU_ASSERT(blob->active.num_clusters == 3); 4400 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 4401 4402 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4403 poll_threads(); 4404 CU_ASSERT(g_bserrno == 0); 4405 /* Sync must not change anything */ 4406 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4407 CU_ASSERT(blob->active.num_clusters == 3); 4408 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 4409 4410 spdk_blob_close(blob, blob_op_complete, NULL); 4411 poll_threads(); 4412 CU_ASSERT(g_bserrno == 0); 4413 4414 ut_bs_reload(&bs, NULL); 4415 4416 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4417 poll_threads(); 4418 CU_ASSERT(g_bserrno == 0); 4419 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4420 blob = g_blob; 4421 4422 /* Check that clusters allocation and size is still the same */ 4423 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4424 CU_ASSERT(blob->active.num_clusters == 3); 4425 4426 spdk_blob_close(blob, blob_op_complete, NULL); 4427 poll_threads(); 4428 CU_ASSERT(g_bserrno == 0); 4429 4430 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4431 poll_threads(); 4432 CU_ASSERT(g_bserrno == 0); 4433 4434 spdk_bs_unload(bs, bs_op_complete, NULL); 4435 poll_threads(); 4436 CU_ASSERT(g_bserrno == 0); 4437 g_bs = NULL; 4438 } 4439 4440 static void 4441 blob_insert_cluster_msg(void) 4442 { 4443 struct spdk_blob_store *bs; 4444 struct spdk_bs_dev *dev; 4445 struct spdk_blob *blob; 4446 struct spdk_blob_opts opts; 4447 spdk_blob_id blobid; 4448 uint64_t free_clusters; 4449 uint64_t new_cluster = 0; 4450 uint32_t cluster_num = 3; 4451 uint32_t extent_page = 0; 4452 4453 dev = init_dev(); 4454 4455 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4456 poll_threads(); 4457 CU_ASSERT(g_bserrno == 0); 4458 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4459 bs = g_bs; 4460 free_clusters = spdk_bs_free_cluster_count(bs); 4461 4462 /* Set blob as thin provisioned */ 4463 ut_spdk_blob_opts_init(&opts); 4464 opts.thin_provision = true; 4465 opts.num_clusters = 4; 4466 4467 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4468 poll_threads(); 4469 CU_ASSERT(g_bserrno == 0); 4470 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4471 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4472 blobid = g_blobid; 4473 4474 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4475 poll_threads(); 4476 CU_ASSERT(g_bserrno == 0); 4477 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4478 blob = g_blob; 4479 4480 CU_ASSERT(blob->active.num_clusters == 4); 4481 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 4482 CU_ASSERT(blob->active.clusters[cluster_num] == 0); 4483 4484 /* Specify cluster_num to allocate and new_cluster will be returned to insert on md_thread. 4485 * This is to simulate behaviour when cluster is allocated after blob creation. 4486 * Such as _spdk_bs_allocate_and_copy_cluster(). */ 4487 _spdk_bs_allocate_cluster(blob, cluster_num, &new_cluster, &extent_page, false); 4488 CU_ASSERT(blob->active.clusters[cluster_num] == 0); 4489 4490 _spdk_blob_insert_cluster_on_md_thread(blob, cluster_num, new_cluster, extent_page, 4491 blob_op_complete, NULL); 4492 poll_threads(); 4493 4494 CU_ASSERT(blob->active.clusters[cluster_num] != 0); 4495 4496 spdk_blob_close(blob, blob_op_complete, NULL); 4497 poll_threads(); 4498 CU_ASSERT(g_bserrno == 0); 4499 4500 ut_bs_reload(&bs, NULL); 4501 4502 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4503 poll_threads(); 4504 CU_ASSERT(g_bserrno == 0); 4505 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4506 blob = g_blob; 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 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4515 poll_threads(); 4516 CU_ASSERT(g_bserrno == 0); 4517 4518 spdk_bs_unload(bs, bs_op_complete, NULL); 4519 poll_threads(); 4520 CU_ASSERT(g_bserrno == 0); 4521 g_bs = NULL; 4522 } 4523 4524 static void 4525 blob_thin_prov_rw(void) 4526 { 4527 static const uint8_t zero[10 * 4096] = { 0 }; 4528 struct spdk_blob_store *bs; 4529 struct spdk_bs_dev *dev; 4530 struct spdk_blob *blob; 4531 struct spdk_io_channel *channel, *channel_thread1; 4532 struct spdk_blob_opts opts; 4533 spdk_blob_id blobid; 4534 uint64_t free_clusters; 4535 uint64_t page_size; 4536 uint8_t payload_read[10 * 4096]; 4537 uint8_t payload_write[10 * 4096]; 4538 uint64_t write_bytes; 4539 uint64_t read_bytes; 4540 4541 dev = init_dev(); 4542 4543 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4544 poll_threads(); 4545 CU_ASSERT(g_bserrno == 0); 4546 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4547 bs = g_bs; 4548 free_clusters = spdk_bs_free_cluster_count(bs); 4549 page_size = spdk_bs_get_page_size(bs); 4550 4551 channel = spdk_bs_alloc_io_channel(bs); 4552 CU_ASSERT(channel != NULL); 4553 4554 ut_spdk_blob_opts_init(&opts); 4555 opts.thin_provision = true; 4556 4557 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4558 poll_threads(); 4559 CU_ASSERT(g_bserrno == 0); 4560 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4561 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4562 blobid = g_blobid; 4563 4564 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4565 poll_threads(); 4566 CU_ASSERT(g_bserrno == 0); 4567 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4568 blob = g_blob; 4569 4570 CU_ASSERT(blob->active.num_clusters == 0); 4571 4572 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4573 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4574 poll_threads(); 4575 CU_ASSERT(g_bserrno == 0); 4576 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4577 CU_ASSERT(blob->active.num_clusters == 5); 4578 4579 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4580 poll_threads(); 4581 CU_ASSERT(g_bserrno == 0); 4582 /* Sync must not change anything */ 4583 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4584 CU_ASSERT(blob->active.num_clusters == 5); 4585 4586 /* Payload should be all zeros from unallocated clusters */ 4587 memset(payload_read, 0xFF, sizeof(payload_read)); 4588 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4589 poll_threads(); 4590 CU_ASSERT(g_bserrno == 0); 4591 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4592 4593 write_bytes = g_dev_write_bytes; 4594 read_bytes = g_dev_read_bytes; 4595 4596 /* Perform write on thread 1. That will allocate cluster on thread 0 via send_msg */ 4597 set_thread(1); 4598 channel_thread1 = spdk_bs_alloc_io_channel(bs); 4599 CU_ASSERT(channel_thread1 != NULL); 4600 memset(payload_write, 0xE5, sizeof(payload_write)); 4601 spdk_blob_io_write(blob, channel_thread1, payload_write, 4, 10, blob_op_complete, NULL); 4602 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4603 /* Perform write on thread 0. That will try to allocate cluster, 4604 * but fail due to another thread issuing the cluster allocation first. */ 4605 set_thread(0); 4606 memset(payload_write, 0xE5, sizeof(payload_write)); 4607 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4608 CU_ASSERT(free_clusters - 2 == spdk_bs_free_cluster_count(bs)); 4609 poll_threads(); 4610 CU_ASSERT(g_bserrno == 0); 4611 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4612 /* For thin-provisioned blob we need to write 20 pages plus one page metadata and 4613 * read 0 bytes */ 4614 if (g_use_extent_table) { 4615 /* Add one more page for EXTENT_PAGE write */ 4616 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 22); 4617 } else { 4618 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 21); 4619 } 4620 CU_ASSERT(g_dev_read_bytes - read_bytes == 0); 4621 4622 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4623 poll_threads(); 4624 CU_ASSERT(g_bserrno == 0); 4625 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4626 4627 spdk_blob_close(blob, blob_op_complete, NULL); 4628 poll_threads(); 4629 CU_ASSERT(g_bserrno == 0); 4630 4631 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4632 poll_threads(); 4633 CU_ASSERT(g_bserrno == 0); 4634 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4635 4636 set_thread(1); 4637 spdk_bs_free_io_channel(channel_thread1); 4638 set_thread(0); 4639 spdk_bs_free_io_channel(channel); 4640 poll_threads(); 4641 4642 /* Unload the blob store */ 4643 spdk_bs_unload(bs, bs_op_complete, NULL); 4644 poll_threads(); 4645 CU_ASSERT(g_bserrno == 0); 4646 g_bs = NULL; 4647 g_blob = NULL; 4648 g_blobid = 0; 4649 } 4650 4651 static void 4652 blob_thin_prov_rle(void) 4653 { 4654 static const uint8_t zero[10 * 4096] = { 0 }; 4655 struct spdk_blob_store *bs; 4656 struct spdk_bs_dev *dev; 4657 struct spdk_blob *blob; 4658 struct spdk_io_channel *channel; 4659 struct spdk_blob_opts opts; 4660 spdk_blob_id blobid; 4661 uint64_t free_clusters; 4662 uint64_t page_size; 4663 uint8_t payload_read[10 * 4096]; 4664 uint8_t payload_write[10 * 4096]; 4665 uint64_t write_bytes; 4666 uint64_t read_bytes; 4667 uint64_t io_unit; 4668 4669 dev = init_dev(); 4670 4671 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4672 poll_threads(); 4673 CU_ASSERT(g_bserrno == 0); 4674 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4675 bs = g_bs; 4676 free_clusters = spdk_bs_free_cluster_count(bs); 4677 page_size = spdk_bs_get_page_size(bs); 4678 4679 ut_spdk_blob_opts_init(&opts); 4680 opts.thin_provision = true; 4681 opts.num_clusters = 5; 4682 4683 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4684 poll_threads(); 4685 CU_ASSERT(g_bserrno == 0); 4686 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4687 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4688 blobid = g_blobid; 4689 4690 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4691 poll_threads(); 4692 CU_ASSERT(g_bserrno == 0); 4693 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4694 blob = g_blob; 4695 4696 channel = spdk_bs_alloc_io_channel(bs); 4697 CU_ASSERT(channel != NULL); 4698 4699 /* Target specifically second cluster in a blob as first allocation */ 4700 io_unit = _spdk_bs_cluster_to_page(bs, 1) * _spdk_bs_io_unit_per_page(bs); 4701 4702 /* Payload should be all zeros from unallocated clusters */ 4703 memset(payload_read, 0xFF, sizeof(payload_read)); 4704 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL); 4705 poll_threads(); 4706 CU_ASSERT(g_bserrno == 0); 4707 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4708 4709 write_bytes = g_dev_write_bytes; 4710 read_bytes = g_dev_read_bytes; 4711 4712 /* Issue write to second cluster in a blob */ 4713 memset(payload_write, 0xE5, sizeof(payload_write)); 4714 spdk_blob_io_write(blob, channel, payload_write, io_unit, 10, blob_op_complete, NULL); 4715 poll_threads(); 4716 CU_ASSERT(g_bserrno == 0); 4717 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4718 /* For thin-provisioned blob we need to write 10 pages plus one page metadata and 4719 * read 0 bytes */ 4720 if (g_use_extent_table) { 4721 /* Add one more page for EXTENT_PAGE write */ 4722 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 12); 4723 } else { 4724 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11); 4725 } 4726 CU_ASSERT(g_dev_read_bytes - read_bytes == 0); 4727 4728 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL); 4729 poll_threads(); 4730 CU_ASSERT(g_bserrno == 0); 4731 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4732 4733 spdk_bs_free_io_channel(channel); 4734 poll_threads(); 4735 4736 spdk_blob_close(blob, blob_op_complete, NULL); 4737 poll_threads(); 4738 CU_ASSERT(g_bserrno == 0); 4739 4740 ut_bs_reload(&bs, NULL); 4741 4742 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4743 poll_threads(); 4744 CU_ASSERT(g_bserrno == 0); 4745 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4746 blob = g_blob; 4747 4748 channel = spdk_bs_alloc_io_channel(bs); 4749 CU_ASSERT(channel != NULL); 4750 4751 /* Read second cluster after blob reload to confirm data written */ 4752 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL); 4753 poll_threads(); 4754 CU_ASSERT(g_bserrno == 0); 4755 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4756 4757 spdk_bs_free_io_channel(channel); 4758 poll_threads(); 4759 4760 spdk_blob_close(blob, blob_op_complete, NULL); 4761 poll_threads(); 4762 CU_ASSERT(g_bserrno == 0); 4763 4764 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4765 poll_threads(); 4766 CU_ASSERT(g_bserrno == 0); 4767 4768 spdk_bs_unload(bs, bs_op_complete, NULL); 4769 poll_threads(); 4770 CU_ASSERT(g_bserrno == 0); 4771 g_bs = NULL; 4772 } 4773 4774 static void 4775 blob_thin_prov_rw_iov(void) 4776 { 4777 static const uint8_t zero[10 * 4096] = { 0 }; 4778 struct spdk_blob_store *bs; 4779 struct spdk_bs_dev *dev; 4780 struct spdk_blob *blob; 4781 struct spdk_io_channel *channel; 4782 struct spdk_blob_opts opts; 4783 spdk_blob_id blobid; 4784 uint64_t free_clusters; 4785 uint8_t payload_read[10 * 4096]; 4786 uint8_t payload_write[10 * 4096]; 4787 struct iovec iov_read[3]; 4788 struct iovec iov_write[3]; 4789 4790 dev = init_dev(); 4791 4792 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4793 poll_threads(); 4794 CU_ASSERT(g_bserrno == 0); 4795 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4796 bs = g_bs; 4797 free_clusters = spdk_bs_free_cluster_count(bs); 4798 4799 channel = spdk_bs_alloc_io_channel(bs); 4800 CU_ASSERT(channel != NULL); 4801 4802 ut_spdk_blob_opts_init(&opts); 4803 opts.thin_provision = true; 4804 4805 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4806 poll_threads(); 4807 CU_ASSERT(g_bserrno == 0); 4808 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4809 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4810 blobid = g_blobid; 4811 4812 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4813 poll_threads(); 4814 CU_ASSERT(g_bserrno == 0); 4815 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4816 blob = g_blob; 4817 4818 CU_ASSERT(blob->active.num_clusters == 0); 4819 4820 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4821 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4822 poll_threads(); 4823 CU_ASSERT(g_bserrno == 0); 4824 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4825 CU_ASSERT(blob->active.num_clusters == 5); 4826 4827 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4828 poll_threads(); 4829 CU_ASSERT(g_bserrno == 0); 4830 /* Sync must not change anything */ 4831 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4832 CU_ASSERT(blob->active.num_clusters == 5); 4833 4834 /* Payload should be all zeros from unallocated clusters */ 4835 memset(payload_read, 0xAA, sizeof(payload_read)); 4836 iov_read[0].iov_base = payload_read; 4837 iov_read[0].iov_len = 3 * 4096; 4838 iov_read[1].iov_base = payload_read + 3 * 4096; 4839 iov_read[1].iov_len = 4 * 4096; 4840 iov_read[2].iov_base = payload_read + 7 * 4096; 4841 iov_read[2].iov_len = 3 * 4096; 4842 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4843 poll_threads(); 4844 CU_ASSERT(g_bserrno == 0); 4845 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4846 4847 memset(payload_write, 0xE5, sizeof(payload_write)); 4848 iov_write[0].iov_base = payload_write; 4849 iov_write[0].iov_len = 1 * 4096; 4850 iov_write[1].iov_base = payload_write + 1 * 4096; 4851 iov_write[1].iov_len = 5 * 4096; 4852 iov_write[2].iov_base = payload_write + 6 * 4096; 4853 iov_write[2].iov_len = 4 * 4096; 4854 4855 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 4856 poll_threads(); 4857 CU_ASSERT(g_bserrno == 0); 4858 4859 memset(payload_read, 0xAA, sizeof(payload_read)); 4860 iov_read[0].iov_base = payload_read; 4861 iov_read[0].iov_len = 3 * 4096; 4862 iov_read[1].iov_base = payload_read + 3 * 4096; 4863 iov_read[1].iov_len = 4 * 4096; 4864 iov_read[2].iov_base = payload_read + 7 * 4096; 4865 iov_read[2].iov_len = 3 * 4096; 4866 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4867 poll_threads(); 4868 CU_ASSERT(g_bserrno == 0); 4869 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4870 4871 spdk_blob_close(blob, blob_op_complete, NULL); 4872 poll_threads(); 4873 CU_ASSERT(g_bserrno == 0); 4874 4875 spdk_bs_free_io_channel(channel); 4876 poll_threads(); 4877 4878 /* Unload the blob store */ 4879 spdk_bs_unload(bs, bs_op_complete, NULL); 4880 poll_threads(); 4881 CU_ASSERT(g_bserrno == 0); 4882 g_bs = NULL; 4883 g_blob = NULL; 4884 g_blobid = 0; 4885 } 4886 4887 struct iter_ctx { 4888 int current_iter; 4889 spdk_blob_id blobid[4]; 4890 }; 4891 4892 static void 4893 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 4894 { 4895 struct iter_ctx *iter_ctx = arg; 4896 spdk_blob_id blobid; 4897 4898 CU_ASSERT(bserrno == 0); 4899 blobid = spdk_blob_get_id(blob); 4900 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 4901 } 4902 4903 static void 4904 bs_load_iter(void) 4905 { 4906 struct spdk_blob_store *bs; 4907 struct spdk_bs_dev *dev; 4908 struct iter_ctx iter_ctx = { 0 }; 4909 struct spdk_blob *blob; 4910 int i, rc; 4911 struct spdk_bs_opts opts; 4912 struct spdk_blob_opts blob_opts; 4913 4914 dev = init_dev(); 4915 spdk_bs_opts_init(&opts); 4916 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4917 4918 /* Initialize a new blob store */ 4919 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 4920 poll_threads(); 4921 CU_ASSERT(g_bserrno == 0); 4922 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4923 bs = g_bs; 4924 4925 ut_spdk_blob_opts_init(&blob_opts); 4926 4927 for (i = 0; i < 4; i++) { 4928 g_bserrno = -1; 4929 g_blobid = SPDK_BLOBID_INVALID; 4930 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 4931 poll_threads(); 4932 CU_ASSERT(g_bserrno == 0); 4933 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4934 iter_ctx.blobid[i] = g_blobid; 4935 4936 g_bserrno = -1; 4937 g_blob = NULL; 4938 spdk_bs_open_blob(bs, g_blobid, blob_op_with_handle_complete, NULL); 4939 poll_threads(); 4940 CU_ASSERT(g_bserrno == 0); 4941 CU_ASSERT(g_blob != NULL); 4942 blob = g_blob; 4943 4944 /* Just save the blobid as an xattr for testing purposes. */ 4945 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 4946 CU_ASSERT(rc == 0); 4947 4948 /* Resize the blob */ 4949 spdk_blob_resize(blob, i, blob_op_complete, NULL); 4950 poll_threads(); 4951 CU_ASSERT(g_bserrno == 0); 4952 4953 spdk_blob_close(blob, blob_op_complete, NULL); 4954 poll_threads(); 4955 CU_ASSERT(g_bserrno == 0); 4956 } 4957 4958 g_bserrno = -1; 4959 spdk_bs_unload(bs, bs_op_complete, NULL); 4960 poll_threads(); 4961 CU_ASSERT(g_bserrno == 0); 4962 4963 dev = init_dev(); 4964 spdk_bs_opts_init(&opts); 4965 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4966 opts.iter_cb_fn = test_iter; 4967 opts.iter_cb_arg = &iter_ctx; 4968 4969 /* Test blob iteration during load after a clean shutdown. */ 4970 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4971 poll_threads(); 4972 CU_ASSERT(g_bserrno == 0); 4973 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4974 bs = g_bs; 4975 4976 /* Dirty shutdown */ 4977 _spdk_bs_free(bs); 4978 4979 dev = init_dev(); 4980 spdk_bs_opts_init(&opts); 4981 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4982 opts.iter_cb_fn = test_iter; 4983 iter_ctx.current_iter = 0; 4984 opts.iter_cb_arg = &iter_ctx; 4985 4986 /* Test blob iteration during load after a dirty shutdown. */ 4987 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4988 poll_threads(); 4989 CU_ASSERT(g_bserrno == 0); 4990 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4991 bs = g_bs; 4992 4993 spdk_bs_unload(bs, bs_op_complete, NULL); 4994 poll_threads(); 4995 CU_ASSERT(g_bserrno == 0); 4996 g_bs = NULL; 4997 } 4998 4999 static void 5000 blob_snapshot_rw(void) 5001 { 5002 static const uint8_t zero[10 * 4096] = { 0 }; 5003 struct spdk_blob_store *bs; 5004 struct spdk_bs_dev *dev; 5005 struct spdk_blob *blob, *snapshot; 5006 struct spdk_io_channel *channel; 5007 struct spdk_blob_opts opts; 5008 spdk_blob_id blobid, snapshotid; 5009 uint64_t free_clusters; 5010 uint64_t cluster_size; 5011 uint64_t page_size; 5012 uint8_t payload_read[10 * 4096]; 5013 uint8_t payload_write[10 * 4096]; 5014 uint64_t write_bytes; 5015 uint64_t read_bytes; 5016 5017 dev = init_dev(); 5018 5019 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5020 poll_threads(); 5021 CU_ASSERT(g_bserrno == 0); 5022 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5023 bs = g_bs; 5024 free_clusters = spdk_bs_free_cluster_count(bs); 5025 cluster_size = spdk_bs_get_cluster_size(bs); 5026 page_size = spdk_bs_get_page_size(bs); 5027 5028 channel = spdk_bs_alloc_io_channel(bs); 5029 CU_ASSERT(channel != NULL); 5030 5031 ut_spdk_blob_opts_init(&opts); 5032 opts.thin_provision = true; 5033 opts.num_clusters = 5; 5034 5035 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5036 poll_threads(); 5037 CU_ASSERT(g_bserrno == 0); 5038 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5039 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5040 blobid = g_blobid; 5041 5042 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5043 poll_threads(); 5044 CU_ASSERT(g_bserrno == 0); 5045 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5046 blob = g_blob; 5047 5048 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5049 5050 memset(payload_read, 0xFF, sizeof(payload_read)); 5051 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 5052 poll_threads(); 5053 CU_ASSERT(g_bserrno == 0); 5054 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 5055 5056 memset(payload_write, 0xE5, sizeof(payload_write)); 5057 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 5058 poll_threads(); 5059 CU_ASSERT(g_bserrno == 0); 5060 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5061 5062 /* Create snapshot from blob */ 5063 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5064 poll_threads(); 5065 CU_ASSERT(g_bserrno == 0); 5066 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5067 snapshotid = g_blobid; 5068 5069 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5070 poll_threads(); 5071 CU_ASSERT(g_bserrno == 0); 5072 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5073 snapshot = g_blob; 5074 CU_ASSERT(snapshot->data_ro == true); 5075 CU_ASSERT(snapshot->md_ro == true); 5076 5077 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 5078 5079 write_bytes = g_dev_write_bytes; 5080 read_bytes = g_dev_read_bytes; 5081 5082 memset(payload_write, 0xAA, sizeof(payload_write)); 5083 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 5084 poll_threads(); 5085 CU_ASSERT(g_bserrno == 0); 5086 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5087 5088 /* For a clone we need to allocate and copy one cluster, update one page of metadata 5089 * and then write 10 pages of payload. 5090 */ 5091 if (g_use_extent_table) { 5092 /* Add one more page for EXTENT_PAGE write */ 5093 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 12 + cluster_size); 5094 } else { 5095 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11 + cluster_size); 5096 } 5097 CU_ASSERT(g_dev_read_bytes - read_bytes == cluster_size); 5098 5099 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 5100 poll_threads(); 5101 CU_ASSERT(g_bserrno == 0); 5102 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 5103 5104 /* Data on snapshot should not change after write to clone */ 5105 memset(payload_write, 0xE5, sizeof(payload_write)); 5106 spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL); 5107 poll_threads(); 5108 CU_ASSERT(g_bserrno == 0); 5109 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 5110 5111 spdk_blob_close(blob, blob_op_complete, NULL); 5112 poll_threads(); 5113 CU_ASSERT(g_bserrno == 0); 5114 5115 spdk_blob_close(snapshot, blob_op_complete, NULL); 5116 poll_threads(); 5117 CU_ASSERT(g_bserrno == 0); 5118 5119 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5120 poll_threads(); 5121 CU_ASSERT(g_bserrno == 0); 5122 5123 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5124 poll_threads(); 5125 CU_ASSERT(g_bserrno == 0); 5126 5127 spdk_bs_free_io_channel(channel); 5128 poll_threads(); 5129 5130 /* Unload the blob store */ 5131 spdk_bs_unload(bs, bs_op_complete, NULL); 5132 poll_threads(); 5133 CU_ASSERT(g_bserrno == 0); 5134 g_bs = NULL; 5135 g_blob = NULL; 5136 g_blobid = 0; 5137 } 5138 5139 static void 5140 blob_snapshot_rw_iov(void) 5141 { 5142 static const uint8_t zero[10 * 4096] = { 0 }; 5143 struct spdk_blob_store *bs; 5144 struct spdk_bs_dev *dev; 5145 struct spdk_blob *blob, *snapshot; 5146 struct spdk_io_channel *channel; 5147 struct spdk_blob_opts opts; 5148 spdk_blob_id blobid, snapshotid; 5149 uint64_t free_clusters; 5150 uint8_t payload_read[10 * 4096]; 5151 uint8_t payload_write[10 * 4096]; 5152 struct iovec iov_read[3]; 5153 struct iovec iov_write[3]; 5154 5155 dev = init_dev(); 5156 5157 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5158 poll_threads(); 5159 CU_ASSERT(g_bserrno == 0); 5160 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5161 bs = g_bs; 5162 free_clusters = spdk_bs_free_cluster_count(bs); 5163 5164 channel = spdk_bs_alloc_io_channel(bs); 5165 CU_ASSERT(channel != NULL); 5166 5167 ut_spdk_blob_opts_init(&opts); 5168 opts.thin_provision = true; 5169 opts.num_clusters = 5; 5170 5171 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5172 poll_threads(); 5173 CU_ASSERT(g_bserrno == 0); 5174 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5175 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5176 blobid = g_blobid; 5177 5178 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5179 poll_threads(); 5180 CU_ASSERT(g_bserrno == 0); 5181 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5182 blob = g_blob; 5183 5184 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5185 5186 /* Create snapshot from blob */ 5187 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5188 poll_threads(); 5189 CU_ASSERT(g_bserrno == 0); 5190 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5191 snapshotid = g_blobid; 5192 5193 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5194 poll_threads(); 5195 CU_ASSERT(g_bserrno == 0); 5196 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5197 snapshot = g_blob; 5198 CU_ASSERT(snapshot->data_ro == true); 5199 CU_ASSERT(snapshot->md_ro == true); 5200 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 5201 5202 /* Payload should be all zeros from unallocated clusters */ 5203 memset(payload_read, 0xAA, sizeof(payload_read)); 5204 iov_read[0].iov_base = payload_read; 5205 iov_read[0].iov_len = 3 * 4096; 5206 iov_read[1].iov_base = payload_read + 3 * 4096; 5207 iov_read[1].iov_len = 4 * 4096; 5208 iov_read[2].iov_base = payload_read + 7 * 4096; 5209 iov_read[2].iov_len = 3 * 4096; 5210 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 5211 poll_threads(); 5212 CU_ASSERT(g_bserrno == 0); 5213 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 5214 5215 memset(payload_write, 0xE5, sizeof(payload_write)); 5216 iov_write[0].iov_base = payload_write; 5217 iov_write[0].iov_len = 1 * 4096; 5218 iov_write[1].iov_base = payload_write + 1 * 4096; 5219 iov_write[1].iov_len = 5 * 4096; 5220 iov_write[2].iov_base = payload_write + 6 * 4096; 5221 iov_write[2].iov_len = 4 * 4096; 5222 5223 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 5224 poll_threads(); 5225 CU_ASSERT(g_bserrno == 0); 5226 5227 memset(payload_read, 0xAA, sizeof(payload_read)); 5228 iov_read[0].iov_base = payload_read; 5229 iov_read[0].iov_len = 3 * 4096; 5230 iov_read[1].iov_base = payload_read + 3 * 4096; 5231 iov_read[1].iov_len = 4 * 4096; 5232 iov_read[2].iov_base = payload_read + 7 * 4096; 5233 iov_read[2].iov_len = 3 * 4096; 5234 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 5235 poll_threads(); 5236 CU_ASSERT(g_bserrno == 0); 5237 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 5238 5239 spdk_blob_close(blob, blob_op_complete, NULL); 5240 poll_threads(); 5241 CU_ASSERT(g_bserrno == 0); 5242 5243 spdk_blob_close(snapshot, blob_op_complete, NULL); 5244 poll_threads(); 5245 CU_ASSERT(g_bserrno == 0); 5246 5247 spdk_bs_free_io_channel(channel); 5248 poll_threads(); 5249 5250 /* Unload the blob store */ 5251 spdk_bs_unload(bs, bs_op_complete, NULL); 5252 poll_threads(); 5253 CU_ASSERT(g_bserrno == 0); 5254 g_bs = NULL; 5255 g_blob = NULL; 5256 g_blobid = 0; 5257 } 5258 5259 /** 5260 * Inflate / decouple parent rw unit tests. 5261 * 5262 * -------------- 5263 * original blob: 0 1 2 3 4 5264 * ,---------+---------+---------+---------+---------. 5265 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 5266 * +---------+---------+---------+---------+---------+ 5267 * snapshot2 | - |yyyyyyyyy| - |yyyyyyyyy| - | 5268 * +---------+---------+---------+---------+---------+ 5269 * blob | - |zzzzzzzzz| - | - | - | 5270 * '---------+---------+---------+---------+---------' 5271 * . . . . . . 5272 * -------- . . . . . . 5273 * inflate: . . . . . . 5274 * ,---------+---------+---------+---------+---------. 5275 * blob |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000| 5276 * '---------+---------+---------+---------+---------' 5277 * 5278 * NOTE: needs to allocate 4 clusters, thin provisioning removed, dependency 5279 * on snapshot2 and snapshot removed . . . 5280 * . . . . . . 5281 * ---------------- . . . . . . 5282 * decouple parent: . . . . . . 5283 * ,---------+---------+---------+---------+---------. 5284 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 5285 * +---------+---------+---------+---------+---------+ 5286 * blob | - |zzzzzzzzz| - |yyyyyyyyy| - | 5287 * '---------+---------+---------+---------+---------' 5288 * 5289 * NOTE: needs to allocate 1 cluster, 3 clusters unallocated, dependency 5290 * on snapshot2 removed and on snapshot still exists. Snapshot2 5291 * should remain a clone of snapshot. 5292 */ 5293 static void 5294 _blob_inflate_rw(bool decouple_parent) 5295 { 5296 struct spdk_blob_store *bs; 5297 struct spdk_bs_dev *dev; 5298 struct spdk_blob *blob, *snapshot, *snapshot2; 5299 struct spdk_io_channel *channel; 5300 struct spdk_blob_opts opts; 5301 spdk_blob_id blobid, snapshotid, snapshot2id; 5302 uint64_t free_clusters; 5303 uint64_t cluster_size; 5304 5305 uint64_t payload_size; 5306 uint8_t *payload_read; 5307 uint8_t *payload_write; 5308 uint8_t *payload_clone; 5309 5310 uint64_t pages_per_cluster; 5311 uint64_t pages_per_payload; 5312 5313 int i; 5314 spdk_blob_id ids[2]; 5315 size_t count; 5316 5317 dev = init_dev(); 5318 5319 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5320 poll_threads(); 5321 CU_ASSERT(g_bserrno == 0); 5322 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5323 bs = g_bs; 5324 5325 free_clusters = spdk_bs_free_cluster_count(bs); 5326 cluster_size = spdk_bs_get_cluster_size(bs); 5327 pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs); 5328 pages_per_payload = pages_per_cluster * 5; 5329 5330 payload_size = cluster_size * 5; 5331 5332 payload_read = malloc(payload_size); 5333 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 5334 5335 payload_write = malloc(payload_size); 5336 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 5337 5338 payload_clone = malloc(payload_size); 5339 SPDK_CU_ASSERT_FATAL(payload_clone != NULL); 5340 5341 channel = spdk_bs_alloc_io_channel(bs); 5342 SPDK_CU_ASSERT_FATAL(channel != NULL); 5343 5344 /* Create blob */ 5345 ut_spdk_blob_opts_init(&opts); 5346 opts.thin_provision = true; 5347 opts.num_clusters = 5; 5348 5349 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5350 poll_threads(); 5351 CU_ASSERT(g_bserrno == 0); 5352 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5353 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5354 blobid = g_blobid; 5355 5356 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5357 poll_threads(); 5358 CU_ASSERT(g_bserrno == 0); 5359 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5360 blob = g_blob; 5361 5362 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5363 5364 /* 1) Initial read should return zeroed payload */ 5365 memset(payload_read, 0xFF, payload_size); 5366 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5367 blob_op_complete, NULL); 5368 poll_threads(); 5369 CU_ASSERT(g_bserrno == 0); 5370 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 5371 5372 /* Fill whole blob with a pattern, except last cluster (to be sure it 5373 * isn't allocated) */ 5374 memset(payload_write, 0xE5, payload_size - cluster_size); 5375 spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload - 5376 pages_per_cluster, blob_op_complete, NULL); 5377 poll_threads(); 5378 CU_ASSERT(g_bserrno == 0); 5379 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5380 5381 /* 2) Create snapshot from blob (first level) */ 5382 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5383 poll_threads(); 5384 CU_ASSERT(g_bserrno == 0); 5385 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5386 snapshotid = g_blobid; 5387 5388 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5389 poll_threads(); 5390 CU_ASSERT(g_bserrno == 0); 5391 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5392 snapshot = g_blob; 5393 CU_ASSERT(snapshot->data_ro == true); 5394 CU_ASSERT(snapshot->md_ro == true); 5395 5396 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 5397 5398 /* Write every second cluster with a pattern. 5399 * 5400 * Last cluster shouldn't be written, to be sure that snapshot nor clone 5401 * doesn't allocate it. 5402 * 5403 * payload_clone stores expected result on "blob" read at the time and 5404 * is used only to check data consistency on clone before and after 5405 * inflation. Initially we fill it with a backing snapshots pattern 5406 * used before. 5407 */ 5408 memset(payload_clone, 0xE5, payload_size - cluster_size); 5409 memset(payload_clone + payload_size - cluster_size, 0x00, cluster_size); 5410 memset(payload_write, 0xAA, payload_size); 5411 for (i = 1; i < 5; i += 2) { 5412 spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster, 5413 pages_per_cluster, blob_op_complete, NULL); 5414 poll_threads(); 5415 CU_ASSERT(g_bserrno == 0); 5416 5417 /* Update expected result */ 5418 memcpy(payload_clone + (cluster_size * i), payload_write, 5419 cluster_size); 5420 } 5421 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5422 5423 /* Check data consistency on clone */ 5424 memset(payload_read, 0xFF, payload_size); 5425 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5426 blob_op_complete, NULL); 5427 poll_threads(); 5428 CU_ASSERT(g_bserrno == 0); 5429 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5430 5431 /* 3) Create second levels snapshot from blob */ 5432 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5433 poll_threads(); 5434 CU_ASSERT(g_bserrno == 0); 5435 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5436 snapshot2id = g_blobid; 5437 5438 spdk_bs_open_blob(bs, snapshot2id, blob_op_with_handle_complete, NULL); 5439 poll_threads(); 5440 CU_ASSERT(g_bserrno == 0); 5441 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5442 snapshot2 = g_blob; 5443 CU_ASSERT(snapshot2->data_ro == true); 5444 CU_ASSERT(snapshot2->md_ro == true); 5445 5446 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 5); 5447 5448 CU_ASSERT(snapshot2->parent_id == snapshotid); 5449 5450 /* Write one cluster on the top level blob. This cluster (1) covers 5451 * already allocated cluster in the snapshot2, so shouldn't be inflated 5452 * at all */ 5453 spdk_blob_io_write(blob, channel, payload_write, pages_per_cluster, 5454 pages_per_cluster, blob_op_complete, NULL); 5455 poll_threads(); 5456 CU_ASSERT(g_bserrno == 0); 5457 5458 /* Update expected result */ 5459 memcpy(payload_clone + cluster_size, payload_write, cluster_size); 5460 5461 /* Check data consistency on clone */ 5462 memset(payload_read, 0xFF, payload_size); 5463 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5464 blob_op_complete, NULL); 5465 poll_threads(); 5466 CU_ASSERT(g_bserrno == 0); 5467 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5468 5469 5470 /* Close all blobs */ 5471 spdk_blob_close(blob, blob_op_complete, NULL); 5472 poll_threads(); 5473 CU_ASSERT(g_bserrno == 0); 5474 5475 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5476 poll_threads(); 5477 CU_ASSERT(g_bserrno == 0); 5478 5479 spdk_blob_close(snapshot, blob_op_complete, NULL); 5480 poll_threads(); 5481 CU_ASSERT(g_bserrno == 0); 5482 5483 /* Check snapshot-clone relations */ 5484 count = 2; 5485 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5486 CU_ASSERT(count == 1); 5487 CU_ASSERT(ids[0] == snapshot2id); 5488 5489 count = 2; 5490 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5491 CU_ASSERT(count == 1); 5492 CU_ASSERT(ids[0] == blobid); 5493 5494 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshot2id); 5495 5496 free_clusters = spdk_bs_free_cluster_count(bs); 5497 if (!decouple_parent) { 5498 /* Do full blob inflation */ 5499 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 5500 poll_threads(); 5501 CU_ASSERT(g_bserrno == 0); 5502 5503 /* All clusters should be inflated (except one already allocated 5504 * in a top level blob) */ 5505 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 4); 5506 5507 /* Check if relation tree updated correctly */ 5508 count = 2; 5509 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5510 5511 /* snapshotid have one clone */ 5512 CU_ASSERT(count == 1); 5513 CU_ASSERT(ids[0] == snapshot2id); 5514 5515 /* snapshot2id have no clones */ 5516 count = 2; 5517 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5518 CU_ASSERT(count == 0); 5519 5520 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5521 } else { 5522 /* Decouple parent of blob */ 5523 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 5524 poll_threads(); 5525 CU_ASSERT(g_bserrno == 0); 5526 5527 /* Only one cluster from a parent should be inflated (second one 5528 * is covered by a cluster written on a top level blob, and 5529 * already allocated) */ 5530 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 1); 5531 5532 /* Check if relation tree updated correctly */ 5533 count = 2; 5534 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5535 5536 /* snapshotid have two clones now */ 5537 CU_ASSERT(count == 2); 5538 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5539 CU_ASSERT(ids[0] == snapshot2id || ids[1] == snapshot2id); 5540 5541 /* snapshot2id have no clones */ 5542 count = 2; 5543 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5544 CU_ASSERT(count == 0); 5545 5546 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5547 } 5548 5549 /* Try to delete snapshot2 (should pass) */ 5550 spdk_bs_delete_blob(bs, snapshot2id, blob_op_complete, NULL); 5551 poll_threads(); 5552 CU_ASSERT(g_bserrno == 0); 5553 5554 /* Try to delete base snapshot */ 5555 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5556 poll_threads(); 5557 CU_ASSERT(g_bserrno == 0); 5558 5559 /* Reopen blob after snapshot deletion */ 5560 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5561 poll_threads(); 5562 CU_ASSERT(g_bserrno == 0); 5563 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5564 blob = g_blob; 5565 5566 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5567 5568 /* Check data consistency on inflated blob */ 5569 memset(payload_read, 0xFF, payload_size); 5570 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5571 blob_op_complete, NULL); 5572 poll_threads(); 5573 CU_ASSERT(g_bserrno == 0); 5574 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5575 5576 spdk_blob_close(blob, blob_op_complete, NULL); 5577 poll_threads(); 5578 CU_ASSERT(g_bserrno == 0); 5579 5580 spdk_bs_free_io_channel(channel); 5581 poll_threads(); 5582 5583 /* Unload the blob store */ 5584 spdk_bs_unload(bs, bs_op_complete, NULL); 5585 poll_threads(); 5586 CU_ASSERT(g_bserrno == 0); 5587 g_bs = NULL; 5588 g_blob = NULL; 5589 g_blobid = 0; 5590 5591 free(payload_read); 5592 free(payload_write); 5593 free(payload_clone); 5594 } 5595 5596 static void 5597 blob_inflate_rw(void) 5598 { 5599 _blob_inflate_rw(false); 5600 _blob_inflate_rw(true); 5601 } 5602 5603 /** 5604 * Snapshot-clones relation test 5605 * 5606 * snapshot 5607 * | 5608 * +-----+-----+ 5609 * | | 5610 * blob(ro) snapshot2 5611 * | | 5612 * clone2 clone 5613 */ 5614 static void 5615 blob_relations(void) 5616 { 5617 struct spdk_blob_store *bs; 5618 struct spdk_bs_dev *dev; 5619 struct spdk_bs_opts bs_opts; 5620 struct spdk_blob_opts opts; 5621 struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2; 5622 spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2; 5623 int rc; 5624 size_t count; 5625 spdk_blob_id ids[10] = {}; 5626 5627 dev = init_dev(); 5628 spdk_bs_opts_init(&bs_opts); 5629 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5630 5631 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 5632 poll_threads(); 5633 CU_ASSERT(g_bserrno == 0); 5634 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5635 bs = g_bs; 5636 5637 /* 1. Create blob with 10 clusters */ 5638 5639 ut_spdk_blob_opts_init(&opts); 5640 opts.num_clusters = 10; 5641 5642 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5643 poll_threads(); 5644 CU_ASSERT(g_bserrno == 0); 5645 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5646 blobid = g_blobid; 5647 5648 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5649 poll_threads(); 5650 CU_ASSERT(g_bserrno == 0); 5651 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5652 blob = g_blob; 5653 5654 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5655 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5656 CU_ASSERT(!spdk_blob_is_clone(blob)); 5657 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob)); 5658 5659 /* blob should not have underlying snapshot nor clones */ 5660 CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID); 5661 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5662 count = SPDK_COUNTOF(ids); 5663 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5664 CU_ASSERT(rc == 0); 5665 CU_ASSERT(count == 0); 5666 5667 5668 /* 2. Create snapshot */ 5669 5670 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5671 poll_threads(); 5672 CU_ASSERT(g_bserrno == 0); 5673 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5674 snapshotid = g_blobid; 5675 5676 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5677 poll_threads(); 5678 CU_ASSERT(g_bserrno == 0); 5679 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5680 snapshot = g_blob; 5681 5682 CU_ASSERT(spdk_blob_is_read_only(snapshot)); 5683 CU_ASSERT(spdk_blob_is_snapshot(snapshot)); 5684 CU_ASSERT(!spdk_blob_is_clone(snapshot)); 5685 CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID); 5686 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5687 5688 /* Check if original blob is converted to the clone of snapshot */ 5689 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5690 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5691 CU_ASSERT(spdk_blob_is_clone(blob)); 5692 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5693 CU_ASSERT(blob->parent_id == snapshotid); 5694 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5695 5696 count = SPDK_COUNTOF(ids); 5697 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5698 CU_ASSERT(rc == 0); 5699 CU_ASSERT(count == 1); 5700 CU_ASSERT(ids[0] == blobid); 5701 5702 5703 /* 3. Create clone from snapshot */ 5704 5705 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 5706 poll_threads(); 5707 CU_ASSERT(g_bserrno == 0); 5708 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5709 cloneid = g_blobid; 5710 5711 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 5712 poll_threads(); 5713 CU_ASSERT(g_bserrno == 0); 5714 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5715 clone = g_blob; 5716 5717 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5718 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5719 CU_ASSERT(spdk_blob_is_clone(clone)); 5720 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5721 CU_ASSERT(clone->parent_id == snapshotid); 5722 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 5723 5724 count = SPDK_COUNTOF(ids); 5725 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5726 CU_ASSERT(rc == 0); 5727 CU_ASSERT(count == 0); 5728 5729 /* Check if clone is on the snapshot's list */ 5730 count = SPDK_COUNTOF(ids); 5731 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5732 CU_ASSERT(rc == 0); 5733 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5734 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 5735 5736 5737 /* 4. Create snapshot of the clone */ 5738 5739 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 5740 poll_threads(); 5741 CU_ASSERT(g_bserrno == 0); 5742 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5743 snapshotid2 = g_blobid; 5744 5745 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 5746 poll_threads(); 5747 CU_ASSERT(g_bserrno == 0); 5748 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5749 snapshot2 = g_blob; 5750 5751 CU_ASSERT(spdk_blob_is_read_only(snapshot2)); 5752 CU_ASSERT(spdk_blob_is_snapshot(snapshot2)); 5753 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 5754 CU_ASSERT(snapshot2->parent_id == snapshotid); 5755 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5756 5757 /* Check if clone is converted to the clone of snapshot2 and snapshot2 5758 * is a child of snapshot */ 5759 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5760 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5761 CU_ASSERT(spdk_blob_is_clone(clone)); 5762 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5763 CU_ASSERT(clone->parent_id == snapshotid2); 5764 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5765 5766 count = SPDK_COUNTOF(ids); 5767 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5768 CU_ASSERT(rc == 0); 5769 CU_ASSERT(count == 1); 5770 CU_ASSERT(ids[0] == cloneid); 5771 5772 5773 /* 5. Try to create clone from read only blob */ 5774 5775 /* Mark blob as read only */ 5776 spdk_blob_set_read_only(blob); 5777 spdk_blob_sync_md(blob, blob_op_complete, NULL); 5778 poll_threads(); 5779 CU_ASSERT(g_bserrno == 0); 5780 5781 /* Check if previously created blob is read only clone */ 5782 CU_ASSERT(spdk_blob_is_read_only(blob)); 5783 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5784 CU_ASSERT(spdk_blob_is_clone(blob)); 5785 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5786 5787 /* Create clone from read only blob */ 5788 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5789 poll_threads(); 5790 CU_ASSERT(g_bserrno == 0); 5791 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5792 cloneid2 = g_blobid; 5793 5794 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 5795 poll_threads(); 5796 CU_ASSERT(g_bserrno == 0); 5797 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5798 clone2 = g_blob; 5799 5800 CU_ASSERT(!spdk_blob_is_read_only(clone2)); 5801 CU_ASSERT(!spdk_blob_is_snapshot(clone2)); 5802 CU_ASSERT(spdk_blob_is_clone(clone2)); 5803 CU_ASSERT(spdk_blob_is_thin_provisioned(clone2)); 5804 5805 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5806 5807 count = SPDK_COUNTOF(ids); 5808 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5809 CU_ASSERT(rc == 0); 5810 5811 CU_ASSERT(count == 1); 5812 CU_ASSERT(ids[0] == cloneid2); 5813 5814 /* Close blobs */ 5815 5816 spdk_blob_close(clone2, blob_op_complete, NULL); 5817 poll_threads(); 5818 CU_ASSERT(g_bserrno == 0); 5819 5820 spdk_blob_close(blob, blob_op_complete, NULL); 5821 poll_threads(); 5822 CU_ASSERT(g_bserrno == 0); 5823 5824 spdk_blob_close(clone, blob_op_complete, NULL); 5825 poll_threads(); 5826 CU_ASSERT(g_bserrno == 0); 5827 5828 spdk_blob_close(snapshot, blob_op_complete, NULL); 5829 poll_threads(); 5830 CU_ASSERT(g_bserrno == 0); 5831 5832 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5833 poll_threads(); 5834 CU_ASSERT(g_bserrno == 0); 5835 5836 /* Try to delete snapshot with more than 1 clone */ 5837 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5838 poll_threads(); 5839 CU_ASSERT(g_bserrno != 0); 5840 5841 ut_bs_reload(&bs, &bs_opts); 5842 5843 /* NULL ids array should return number of clones in count */ 5844 count = SPDK_COUNTOF(ids); 5845 rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count); 5846 CU_ASSERT(rc == -ENOMEM); 5847 CU_ASSERT(count == 2); 5848 5849 /* incorrect array size */ 5850 count = 1; 5851 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5852 CU_ASSERT(rc == -ENOMEM); 5853 CU_ASSERT(count == 2); 5854 5855 5856 /* Verify structure of loaded blob store */ 5857 5858 /* snapshot */ 5859 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5860 5861 count = SPDK_COUNTOF(ids); 5862 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5863 CU_ASSERT(rc == 0); 5864 CU_ASSERT(count == 2); 5865 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5866 CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2); 5867 5868 /* blob */ 5869 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5870 count = SPDK_COUNTOF(ids); 5871 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5872 CU_ASSERT(rc == 0); 5873 CU_ASSERT(count == 1); 5874 CU_ASSERT(ids[0] == cloneid2); 5875 5876 /* clone */ 5877 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5878 count = SPDK_COUNTOF(ids); 5879 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5880 CU_ASSERT(rc == 0); 5881 CU_ASSERT(count == 0); 5882 5883 /* snapshot2 */ 5884 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5885 count = SPDK_COUNTOF(ids); 5886 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5887 CU_ASSERT(rc == 0); 5888 CU_ASSERT(count == 1); 5889 CU_ASSERT(ids[0] == cloneid); 5890 5891 /* clone2 */ 5892 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5893 count = SPDK_COUNTOF(ids); 5894 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 5895 CU_ASSERT(rc == 0); 5896 CU_ASSERT(count == 0); 5897 5898 /* Try to delete blob that user should not be able to remove */ 5899 5900 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5901 poll_threads(); 5902 CU_ASSERT(g_bserrno != 0); 5903 5904 /* Remove all blobs */ 5905 5906 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 5907 poll_threads(); 5908 CU_ASSERT(g_bserrno == 0); 5909 5910 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5911 poll_threads(); 5912 CU_ASSERT(g_bserrno == 0); 5913 5914 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 5915 poll_threads(); 5916 CU_ASSERT(g_bserrno == 0); 5917 5918 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5919 poll_threads(); 5920 CU_ASSERT(g_bserrno == 0); 5921 5922 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5923 poll_threads(); 5924 CU_ASSERT(g_bserrno == 0); 5925 5926 spdk_bs_unload(bs, bs_op_complete, NULL); 5927 poll_threads(); 5928 CU_ASSERT(g_bserrno == 0); 5929 5930 g_bs = NULL; 5931 } 5932 5933 /** 5934 * Snapshot-clones relation test 2 5935 * 5936 * snapshot1 5937 * | 5938 * snapshot2 5939 * | 5940 * +-----+-----+ 5941 * | | 5942 * blob(ro) snapshot3 5943 * | | 5944 * | snapshot4 5945 * | | | 5946 * clone2 clone clone3 5947 */ 5948 static void 5949 blob_relations2(void) 5950 { 5951 struct spdk_blob_store *bs; 5952 struct spdk_bs_dev *dev; 5953 struct spdk_bs_opts bs_opts; 5954 struct spdk_blob_opts opts; 5955 struct spdk_blob *blob, *snapshot1, *snapshot2, *snapshot3, *snapshot4, *clone, *clone2; 5956 spdk_blob_id blobid, snapshotid1, snapshotid2, snapshotid3, snapshotid4, cloneid, cloneid2, 5957 cloneid3; 5958 int rc; 5959 size_t count; 5960 spdk_blob_id ids[10] = {}; 5961 5962 dev = init_dev(); 5963 spdk_bs_opts_init(&bs_opts); 5964 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5965 5966 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 5967 poll_threads(); 5968 CU_ASSERT(g_bserrno == 0); 5969 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5970 bs = g_bs; 5971 5972 /* 1. Create blob with 10 clusters */ 5973 5974 ut_spdk_blob_opts_init(&opts); 5975 opts.num_clusters = 10; 5976 5977 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5978 poll_threads(); 5979 CU_ASSERT(g_bserrno == 0); 5980 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5981 blobid = g_blobid; 5982 5983 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5984 poll_threads(); 5985 CU_ASSERT(g_bserrno == 0); 5986 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5987 blob = g_blob; 5988 5989 /* 2. Create snapshot1 */ 5990 5991 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5992 poll_threads(); 5993 CU_ASSERT(g_bserrno == 0); 5994 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5995 snapshotid1 = g_blobid; 5996 5997 spdk_bs_open_blob(bs, snapshotid1, blob_op_with_handle_complete, NULL); 5998 poll_threads(); 5999 CU_ASSERT(g_bserrno == 0); 6000 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6001 snapshot1 = g_blob; 6002 6003 CU_ASSERT(snapshot1->parent_id == SPDK_BLOBID_INVALID); 6004 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid1) == SPDK_BLOBID_INVALID); 6005 6006 CU_ASSERT(blob->parent_id == snapshotid1); 6007 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1); 6008 6009 /* Check if blob is the clone of snapshot1 */ 6010 CU_ASSERT(blob->parent_id == snapshotid1); 6011 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1); 6012 6013 count = SPDK_COUNTOF(ids); 6014 rc = spdk_blob_get_clones(bs, snapshotid1, ids, &count); 6015 CU_ASSERT(rc == 0); 6016 CU_ASSERT(count == 1); 6017 CU_ASSERT(ids[0] == blobid); 6018 6019 /* 3. Create another snapshot */ 6020 6021 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6022 poll_threads(); 6023 CU_ASSERT(g_bserrno == 0); 6024 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6025 snapshotid2 = g_blobid; 6026 6027 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 6028 poll_threads(); 6029 CU_ASSERT(g_bserrno == 0); 6030 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6031 snapshot2 = g_blob; 6032 6033 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 6034 CU_ASSERT(snapshot2->parent_id == snapshotid1); 6035 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid1); 6036 6037 /* Check if snapshot2 is the clone of snapshot1 and blob 6038 * is a child of snapshot2 */ 6039 CU_ASSERT(blob->parent_id == snapshotid2); 6040 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2); 6041 6042 count = SPDK_COUNTOF(ids); 6043 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6044 CU_ASSERT(rc == 0); 6045 CU_ASSERT(count == 1); 6046 CU_ASSERT(ids[0] == blobid); 6047 6048 /* 4. Create clone from snapshot */ 6049 6050 spdk_bs_create_clone(bs, snapshotid2, NULL, blob_op_with_id_complete, NULL); 6051 poll_threads(); 6052 CU_ASSERT(g_bserrno == 0); 6053 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6054 cloneid = g_blobid; 6055 6056 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 6057 poll_threads(); 6058 CU_ASSERT(g_bserrno == 0); 6059 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6060 clone = g_blob; 6061 6062 CU_ASSERT(clone->parent_id == snapshotid2); 6063 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 6064 6065 /* Check if clone is on the snapshot's list */ 6066 count = SPDK_COUNTOF(ids); 6067 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6068 CU_ASSERT(rc == 0); 6069 CU_ASSERT(count == 2); 6070 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 6071 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 6072 6073 /* 5. Create snapshot of the clone */ 6074 6075 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 6076 poll_threads(); 6077 CU_ASSERT(g_bserrno == 0); 6078 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6079 snapshotid3 = g_blobid; 6080 6081 spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL); 6082 poll_threads(); 6083 CU_ASSERT(g_bserrno == 0); 6084 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6085 snapshot3 = g_blob; 6086 6087 CU_ASSERT(snapshot3->parent_id == snapshotid2); 6088 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2); 6089 6090 /* Check if clone is converted to the clone of snapshot3 and snapshot3 6091 * is a child of snapshot2 */ 6092 CU_ASSERT(clone->parent_id == snapshotid3); 6093 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 6094 6095 count = SPDK_COUNTOF(ids); 6096 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 6097 CU_ASSERT(rc == 0); 6098 CU_ASSERT(count == 1); 6099 CU_ASSERT(ids[0] == cloneid); 6100 6101 /* 6. Create another snapshot of the clone */ 6102 6103 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 6104 poll_threads(); 6105 CU_ASSERT(g_bserrno == 0); 6106 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6107 snapshotid4 = g_blobid; 6108 6109 spdk_bs_open_blob(bs, snapshotid4, blob_op_with_handle_complete, NULL); 6110 poll_threads(); 6111 CU_ASSERT(g_bserrno == 0); 6112 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6113 snapshot4 = g_blob; 6114 6115 CU_ASSERT(snapshot4->parent_id == snapshotid3); 6116 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid4) == snapshotid3); 6117 6118 /* Check if clone is converted to the clone of snapshot4 and snapshot4 6119 * is a child of snapshot3 */ 6120 CU_ASSERT(clone->parent_id == snapshotid4); 6121 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid4); 6122 6123 count = SPDK_COUNTOF(ids); 6124 rc = spdk_blob_get_clones(bs, snapshotid4, ids, &count); 6125 CU_ASSERT(rc == 0); 6126 CU_ASSERT(count == 1); 6127 CU_ASSERT(ids[0] == cloneid); 6128 6129 /* 7. Remove snapshot 4 */ 6130 6131 spdk_blob_close(snapshot4, blob_op_complete, NULL); 6132 poll_threads(); 6133 CU_ASSERT(g_bserrno == 0); 6134 6135 spdk_bs_delete_blob(bs, snapshotid4, blob_op_complete, NULL); 6136 poll_threads(); 6137 CU_ASSERT(g_bserrno == 0); 6138 6139 /* Check if relations are back to state from before creating snapshot 4 */ 6140 CU_ASSERT(clone->parent_id == snapshotid3); 6141 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 6142 6143 count = SPDK_COUNTOF(ids); 6144 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 6145 CU_ASSERT(rc == 0); 6146 CU_ASSERT(count == 1); 6147 CU_ASSERT(ids[0] == cloneid); 6148 6149 /* 8. Create second clone of snapshot 3 and try to remove snapshot 3 */ 6150 6151 spdk_bs_create_clone(bs, snapshotid3, NULL, blob_op_with_id_complete, NULL); 6152 poll_threads(); 6153 CU_ASSERT(g_bserrno == 0); 6154 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6155 cloneid3 = g_blobid; 6156 6157 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 6158 poll_threads(); 6159 CU_ASSERT(g_bserrno != 0); 6160 6161 /* 9. Open snapshot 3 again and try to remove it while clone 3 is closed */ 6162 6163 spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL); 6164 poll_threads(); 6165 CU_ASSERT(g_bserrno == 0); 6166 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6167 snapshot3 = g_blob; 6168 6169 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 6170 poll_threads(); 6171 CU_ASSERT(g_bserrno != 0); 6172 6173 spdk_blob_close(snapshot3, blob_op_complete, NULL); 6174 poll_threads(); 6175 CU_ASSERT(g_bserrno == 0); 6176 6177 spdk_bs_delete_blob(bs, cloneid3, blob_op_complete, NULL); 6178 poll_threads(); 6179 CU_ASSERT(g_bserrno == 0); 6180 6181 /* 10. Remove snapshot 1 */ 6182 6183 spdk_blob_close(snapshot1, blob_op_complete, NULL); 6184 poll_threads(); 6185 CU_ASSERT(g_bserrno == 0); 6186 6187 spdk_bs_delete_blob(bs, snapshotid1, blob_op_complete, NULL); 6188 poll_threads(); 6189 CU_ASSERT(g_bserrno == 0); 6190 6191 /* Check if relations are back to state from before creating snapshot 4 (before step 6) */ 6192 CU_ASSERT(snapshot2->parent_id == SPDK_BLOBID_INVALID); 6193 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID); 6194 6195 count = SPDK_COUNTOF(ids); 6196 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6197 CU_ASSERT(rc == 0); 6198 CU_ASSERT(count == 2); 6199 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 6200 CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3); 6201 6202 /* 11. Try to create clone from read only blob */ 6203 6204 /* Mark blob as read only */ 6205 spdk_blob_set_read_only(blob); 6206 spdk_blob_sync_md(blob, blob_op_complete, NULL); 6207 poll_threads(); 6208 CU_ASSERT(g_bserrno == 0); 6209 6210 /* Create clone from read only blob */ 6211 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6212 poll_threads(); 6213 CU_ASSERT(g_bserrno == 0); 6214 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6215 cloneid2 = g_blobid; 6216 6217 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 6218 poll_threads(); 6219 CU_ASSERT(g_bserrno == 0); 6220 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6221 clone2 = g_blob; 6222 6223 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 6224 6225 count = SPDK_COUNTOF(ids); 6226 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 6227 CU_ASSERT(rc == 0); 6228 CU_ASSERT(count == 1); 6229 CU_ASSERT(ids[0] == cloneid2); 6230 6231 /* Close blobs */ 6232 6233 spdk_blob_close(clone2, blob_op_complete, NULL); 6234 poll_threads(); 6235 CU_ASSERT(g_bserrno == 0); 6236 6237 spdk_blob_close(blob, blob_op_complete, NULL); 6238 poll_threads(); 6239 CU_ASSERT(g_bserrno == 0); 6240 6241 spdk_blob_close(clone, blob_op_complete, NULL); 6242 poll_threads(); 6243 CU_ASSERT(g_bserrno == 0); 6244 6245 spdk_blob_close(snapshot2, blob_op_complete, NULL); 6246 poll_threads(); 6247 CU_ASSERT(g_bserrno == 0); 6248 6249 spdk_blob_close(snapshot3, blob_op_complete, NULL); 6250 poll_threads(); 6251 CU_ASSERT(g_bserrno == 0); 6252 6253 ut_bs_reload(&bs, &bs_opts); 6254 6255 /* Verify structure of loaded blob store */ 6256 6257 /* snapshot2 */ 6258 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID); 6259 6260 count = SPDK_COUNTOF(ids); 6261 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6262 CU_ASSERT(rc == 0); 6263 CU_ASSERT(count == 2); 6264 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 6265 CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3); 6266 6267 /* blob */ 6268 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2); 6269 count = SPDK_COUNTOF(ids); 6270 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 6271 CU_ASSERT(rc == 0); 6272 CU_ASSERT(count == 1); 6273 CU_ASSERT(ids[0] == cloneid2); 6274 6275 /* clone */ 6276 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 6277 count = SPDK_COUNTOF(ids); 6278 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 6279 CU_ASSERT(rc == 0); 6280 CU_ASSERT(count == 0); 6281 6282 /* snapshot3 */ 6283 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2); 6284 count = SPDK_COUNTOF(ids); 6285 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 6286 CU_ASSERT(rc == 0); 6287 CU_ASSERT(count == 1); 6288 CU_ASSERT(ids[0] == cloneid); 6289 6290 /* clone2 */ 6291 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 6292 count = SPDK_COUNTOF(ids); 6293 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 6294 CU_ASSERT(rc == 0); 6295 CU_ASSERT(count == 0); 6296 6297 /* Try to delete all blobs in the worse possible order */ 6298 6299 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6300 poll_threads(); 6301 CU_ASSERT(g_bserrno != 0); 6302 6303 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 6304 poll_threads(); 6305 CU_ASSERT(g_bserrno == 0); 6306 6307 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6308 poll_threads(); 6309 CU_ASSERT(g_bserrno != 0); 6310 6311 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 6312 poll_threads(); 6313 CU_ASSERT(g_bserrno == 0); 6314 6315 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6316 poll_threads(); 6317 CU_ASSERT(g_bserrno == 0); 6318 6319 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 6320 poll_threads(); 6321 CU_ASSERT(g_bserrno == 0); 6322 6323 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 6324 poll_threads(); 6325 CU_ASSERT(g_bserrno == 0); 6326 6327 spdk_bs_unload(bs, bs_op_complete, NULL); 6328 poll_threads(); 6329 CU_ASSERT(g_bserrno == 0); 6330 6331 g_bs = NULL; 6332 } 6333 6334 static void 6335 blob_delete_snapshot_power_failure(void) 6336 { 6337 struct spdk_blob_store *bs; 6338 struct spdk_bs_dev *dev; 6339 struct spdk_blob_opts opts; 6340 struct spdk_blob *blob, *snapshot; 6341 struct spdk_power_failure_thresholds thresholds = {}; 6342 spdk_blob_id blobid, snapshotid; 6343 const void *value; 6344 size_t value_len; 6345 size_t count; 6346 spdk_blob_id ids[3] = {}; 6347 int rc; 6348 bool deleted = false; 6349 6350 dev = init_dev(); 6351 6352 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 6353 poll_threads(); 6354 CU_ASSERT(g_bserrno == 0); 6355 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6356 bs = g_bs; 6357 6358 /* Create blob */ 6359 ut_spdk_blob_opts_init(&opts); 6360 opts.num_clusters = 10; 6361 6362 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 6363 poll_threads(); 6364 CU_ASSERT(g_bserrno == 0); 6365 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6366 blobid = g_blobid; 6367 6368 /* Create snapshot */ 6369 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6370 poll_threads(); 6371 CU_ASSERT(g_bserrno == 0); 6372 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6373 snapshotid = g_blobid; 6374 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6375 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6376 6377 thresholds.general_threshold = 1; 6378 while (!deleted) { 6379 dev_set_power_failure_thresholds(thresholds); 6380 6381 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 6382 poll_threads(); 6383 6384 /* Do not shut down cleanly. Assumption is that after snapshot deletion 6385 * reports success, changes to both blobs should already persisted. */ 6386 dev_reset_power_failure_event(); 6387 ut_bs_dirty_load(&bs, NULL); 6388 6389 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6390 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6391 6392 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 6393 poll_threads(); 6394 CU_ASSERT(g_bserrno == 0); 6395 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6396 blob = g_blob; 6397 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true); 6398 6399 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 6400 poll_threads(); 6401 6402 if (g_bserrno == 0) { 6403 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6404 snapshot = g_blob; 6405 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 6406 count = SPDK_COUNTOF(ids); 6407 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 6408 CU_ASSERT(rc == 0); 6409 CU_ASSERT(count == 1); 6410 CU_ASSERT(ids[0] == blobid); 6411 rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_PENDING_REMOVAL, &value, &value_len); 6412 CU_ASSERT(rc != 0); 6413 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(snapshot) == false); 6414 6415 spdk_blob_close(snapshot, blob_op_complete, NULL); 6416 poll_threads(); 6417 CU_ASSERT(g_bserrno == 0); 6418 } else { 6419 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 6420 deleted = true; 6421 } 6422 6423 spdk_blob_close(blob, blob_op_complete, NULL); 6424 poll_threads(); 6425 CU_ASSERT(g_bserrno == 0); 6426 6427 /* Reload blobstore to have the same starting conditions (as the previous blobstore load 6428 * may trigger cleanup after power failure or may not) */ 6429 ut_bs_reload(&bs, NULL); 6430 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6431 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6432 6433 thresholds.general_threshold++; 6434 } 6435 6436 spdk_bs_unload(bs, bs_op_complete, NULL); 6437 poll_threads(); 6438 CU_ASSERT(g_bserrno == 0); 6439 g_bs = NULL; 6440 } 6441 6442 static void 6443 blob_create_snapshot_power_failure(void) 6444 { 6445 struct spdk_blob_store *bs; 6446 struct spdk_bs_dev *dev; 6447 struct spdk_blob_opts opts; 6448 struct spdk_blob *blob, *snapshot; 6449 struct spdk_power_failure_thresholds thresholds = {}; 6450 spdk_blob_id blobid, snapshotid; 6451 const void *value; 6452 size_t value_len; 6453 size_t count; 6454 spdk_blob_id ids[3] = {}; 6455 int rc; 6456 bool created = false; 6457 6458 dev = init_dev(); 6459 6460 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 6461 poll_threads(); 6462 CU_ASSERT(g_bserrno == 0); 6463 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6464 bs = g_bs; 6465 6466 /* Create blob */ 6467 ut_spdk_blob_opts_init(&opts); 6468 opts.num_clusters = 10; 6469 6470 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 6471 poll_threads(); 6472 CU_ASSERT(g_bserrno == 0); 6473 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6474 blobid = g_blobid; 6475 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6476 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6477 6478 thresholds.general_threshold = 1; 6479 while (!created) { 6480 dev_set_power_failure_thresholds(thresholds); 6481 6482 /* Create snapshot */ 6483 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6484 poll_threads(); 6485 snapshotid = g_blobid; 6486 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6487 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6488 6489 /* Do not shut down cleanly. Assumption is that after create snapshot 6490 * reports success, both blobs should be power-fail safe. */ 6491 dev_reset_power_failure_event(); 6492 ut_bs_dirty_load(&bs, NULL); 6493 6494 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6495 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6496 6497 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 6498 poll_threads(); 6499 CU_ASSERT(g_bserrno == 0); 6500 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6501 blob = g_blob; 6502 6503 if (snapshotid != SPDK_BLOBID_INVALID) { 6504 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 6505 poll_threads(); 6506 } 6507 6508 if ((snapshotid != SPDK_BLOBID_INVALID) && (g_bserrno == 0)) { 6509 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6510 snapshot = g_blob; 6511 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true); 6512 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(snapshot) == false); 6513 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 6514 count = SPDK_COUNTOF(ids); 6515 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 6516 CU_ASSERT(rc == 0); 6517 CU_ASSERT(count == 1); 6518 CU_ASSERT(ids[0] == blobid); 6519 rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_IN_PROGRESS, &value, &value_len); 6520 CU_ASSERT(rc != 0); 6521 6522 spdk_blob_close(snapshot, blob_op_complete, NULL); 6523 poll_threads(); 6524 CU_ASSERT(g_bserrno == 0); 6525 created = true; 6526 } else { 6527 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 6528 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == false); 6529 } 6530 6531 spdk_blob_close(blob, blob_op_complete, NULL); 6532 poll_threads(); 6533 CU_ASSERT(g_bserrno == 0); 6534 6535 /* Reload blobstore to have the same starting conditions (as the previous blobstore load 6536 * may trigger cleanup after power failure or may not) */ 6537 ut_bs_reload(&bs, NULL); 6538 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6539 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6540 6541 thresholds.general_threshold++; 6542 } 6543 6544 spdk_bs_unload(bs, bs_op_complete, NULL); 6545 poll_threads(); 6546 CU_ASSERT(g_bserrno == 0); 6547 g_bs = NULL; 6548 } 6549 6550 static void 6551 test_io_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6552 { 6553 uint8_t payload_ff[64 * 512]; 6554 uint8_t payload_aa[64 * 512]; 6555 uint8_t payload_00[64 * 512]; 6556 uint8_t *cluster0, *cluster1; 6557 6558 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6559 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6560 memset(payload_00, 0x00, sizeof(payload_00)); 6561 6562 /* Try to perform I/O with io unit = 512 */ 6563 spdk_blob_io_write(blob, channel, payload_ff, 0, 1, blob_op_complete, NULL); 6564 poll_threads(); 6565 CU_ASSERT(g_bserrno == 0); 6566 6567 /* If thin provisioned is set cluster should be allocated now */ 6568 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 6569 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6570 6571 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 6572 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 6573 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6574 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6575 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 6576 6577 /* Verify write with offset on first page */ 6578 spdk_blob_io_write(blob, channel, payload_ff, 2, 1, blob_op_complete, NULL); 6579 poll_threads(); 6580 CU_ASSERT(g_bserrno == 0); 6581 6582 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6583 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6584 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6585 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6586 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6587 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 6588 6589 /* Verify write with offset on first page */ 6590 spdk_blob_io_write(blob, channel, payload_ff, 4, 4, blob_op_complete, NULL); 6591 poll_threads(); 6592 6593 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6594 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6595 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6596 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6597 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6598 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 6599 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 6600 6601 /* Verify write with offset on second page */ 6602 spdk_blob_io_write(blob, channel, payload_ff, 8, 4, blob_op_complete, NULL); 6603 poll_threads(); 6604 6605 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 6606 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6607 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6608 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6609 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6610 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 6611 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6612 6613 /* Verify write across multiple pages */ 6614 spdk_blob_io_write(blob, channel, payload_aa, 4, 8, blob_op_complete, NULL); 6615 poll_threads(); 6616 6617 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 6618 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6619 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6620 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6621 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6622 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6623 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6624 6625 /* Verify write across multiple clusters */ 6626 spdk_blob_io_write(blob, channel, payload_ff, 28, 8, blob_op_complete, NULL); 6627 poll_threads(); 6628 6629 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6630 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6631 6632 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6633 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6634 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6635 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6636 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6637 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6638 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6639 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6640 6641 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6642 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 6643 6644 /* Verify write to second cluster */ 6645 spdk_blob_io_write(blob, channel, payload_ff, 32 + 12, 2, blob_op_complete, NULL); 6646 poll_threads(); 6647 6648 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6649 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6650 6651 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6652 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 6653 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6654 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6655 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6656 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6657 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6658 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6659 6660 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6661 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 6662 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 6663 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 6664 } 6665 6666 static void 6667 test_io_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6668 { 6669 uint8_t payload_read[64 * 512]; 6670 uint8_t payload_ff[64 * 512]; 6671 uint8_t payload_aa[64 * 512]; 6672 uint8_t payload_00[64 * 512]; 6673 6674 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6675 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6676 memset(payload_00, 0x00, sizeof(payload_00)); 6677 6678 /* Read only first io unit */ 6679 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6680 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6681 * payload_read: F000 0000 | 0000 0000 ... */ 6682 memset(payload_read, 0x00, sizeof(payload_read)); 6683 spdk_blob_io_read(blob, channel, payload_read, 0, 1, blob_op_complete, NULL); 6684 poll_threads(); 6685 CU_ASSERT(g_bserrno == 0); 6686 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6687 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 6688 6689 /* Read four io_units starting from offset = 2 6690 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6691 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6692 * payload_read: F0AA 0000 | 0000 0000 ... */ 6693 6694 memset(payload_read, 0x00, sizeof(payload_read)); 6695 spdk_blob_io_read(blob, channel, payload_read, 2, 4, blob_op_complete, NULL); 6696 poll_threads(); 6697 CU_ASSERT(g_bserrno == 0); 6698 6699 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6700 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6701 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 6702 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 6703 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6704 6705 /* Read eight io_units across multiple pages 6706 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6707 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6708 * payload_read: AAAA AAAA | 0000 0000 ... */ 6709 memset(payload_read, 0x00, sizeof(payload_read)); 6710 spdk_blob_io_read(blob, channel, payload_read, 4, 8, blob_op_complete, NULL); 6711 poll_threads(); 6712 CU_ASSERT(g_bserrno == 0); 6713 6714 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 6715 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6716 6717 /* Read eight io_units across multiple clusters 6718 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 6719 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6720 * payload_read: FFFF FFFF | 0000 0000 ... */ 6721 memset(payload_read, 0x00, sizeof(payload_read)); 6722 spdk_blob_io_read(blob, channel, payload_read, 28, 8, blob_op_complete, NULL); 6723 poll_threads(); 6724 CU_ASSERT(g_bserrno == 0); 6725 6726 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 6727 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6728 6729 /* Read four io_units from second cluster 6730 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6731 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 6732 * payload_read: 00FF 0000 | 0000 0000 ... */ 6733 memset(payload_read, 0x00, sizeof(payload_read)); 6734 spdk_blob_io_read(blob, channel, payload_read, 32 + 10, 4, blob_op_complete, NULL); 6735 poll_threads(); 6736 CU_ASSERT(g_bserrno == 0); 6737 6738 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 6739 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 6740 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6741 6742 /* Read second cluster 6743 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6744 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 6745 * payload_read: FFFF 0000 | 0000 FF00 ... */ 6746 memset(payload_read, 0x00, sizeof(payload_read)); 6747 spdk_blob_io_read(blob, channel, payload_read, 32, 32, blob_op_complete, NULL); 6748 poll_threads(); 6749 CU_ASSERT(g_bserrno == 0); 6750 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 6751 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 6752 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 6753 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 6754 6755 /* Read whole two clusters 6756 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6757 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 6758 memset(payload_read, 0x00, sizeof(payload_read)); 6759 spdk_blob_io_read(blob, channel, payload_read, 0, 64, blob_op_complete, NULL); 6760 poll_threads(); 6761 CU_ASSERT(g_bserrno == 0); 6762 6763 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6764 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6765 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 6766 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 6767 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 6768 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 6769 6770 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 6771 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 6772 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 6773 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 6774 } 6775 6776 6777 static void 6778 test_io_unmap(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6779 { 6780 uint8_t payload_ff[64 * 512]; 6781 uint8_t payload_aa[64 * 512]; 6782 uint8_t payload_00[64 * 512]; 6783 uint8_t *cluster0, *cluster1; 6784 6785 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6786 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6787 memset(payload_00, 0x00, sizeof(payload_00)); 6788 6789 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6790 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6791 6792 /* Unmap */ 6793 spdk_blob_io_unmap(blob, channel, 0, 64, blob_op_complete, NULL); 6794 poll_threads(); 6795 6796 CU_ASSERT(g_bserrno == 0); 6797 6798 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 6799 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 6800 } 6801 6802 static void 6803 test_io_zeroes(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6804 { 6805 uint8_t payload_ff[64 * 512]; 6806 uint8_t payload_aa[64 * 512]; 6807 uint8_t payload_00[64 * 512]; 6808 uint8_t *cluster0, *cluster1; 6809 6810 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6811 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6812 memset(payload_00, 0x00, sizeof(payload_00)); 6813 6814 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6815 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6816 6817 /* Write zeroes */ 6818 spdk_blob_io_write_zeroes(blob, channel, 0, 64, blob_op_complete, NULL); 6819 poll_threads(); 6820 6821 CU_ASSERT(g_bserrno == 0); 6822 6823 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 6824 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 6825 } 6826 6827 6828 static void 6829 test_iov_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6830 { 6831 uint8_t payload_ff[64 * 512]; 6832 uint8_t payload_aa[64 * 512]; 6833 uint8_t payload_00[64 * 512]; 6834 uint8_t *cluster0, *cluster1; 6835 struct iovec iov[4]; 6836 6837 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6838 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6839 memset(payload_00, 0x00, sizeof(payload_00)); 6840 6841 /* Try to perform I/O with io unit = 512 */ 6842 iov[0].iov_base = payload_ff; 6843 iov[0].iov_len = 1 * 512; 6844 spdk_blob_io_writev(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 6845 poll_threads(); 6846 CU_ASSERT(g_bserrno == 0); 6847 6848 /* If thin provisioned is set cluster should be allocated now */ 6849 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 6850 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6851 6852 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 6853 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 6854 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6855 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6856 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 6857 6858 /* Verify write with offset on first page */ 6859 iov[0].iov_base = payload_ff; 6860 iov[0].iov_len = 1 * 512; 6861 spdk_blob_io_writev(blob, channel, iov, 1, 2, 1, blob_op_complete, NULL); 6862 poll_threads(); 6863 CU_ASSERT(g_bserrno == 0); 6864 6865 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6866 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6867 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6868 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6869 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6870 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 6871 6872 /* Verify write with offset on first page */ 6873 iov[0].iov_base = payload_ff; 6874 iov[0].iov_len = 4 * 512; 6875 spdk_blob_io_writev(blob, channel, iov, 1, 4, 4, blob_op_complete, NULL); 6876 poll_threads(); 6877 6878 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6879 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6880 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6881 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6882 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6883 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 6884 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 6885 6886 /* Verify write with offset on second page */ 6887 iov[0].iov_base = payload_ff; 6888 iov[0].iov_len = 4 * 512; 6889 spdk_blob_io_writev(blob, channel, iov, 1, 8, 4, blob_op_complete, NULL); 6890 poll_threads(); 6891 6892 /* cluster0: [ F0F0 FFFF | FFFF 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, 8 * 512) == 0); 6898 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6899 6900 /* Verify write across multiple pages */ 6901 iov[0].iov_base = payload_aa; 6902 iov[0].iov_len = 8 * 512; 6903 spdk_blob_io_writev(blob, channel, iov, 1, 4, 8, blob_op_complete, NULL); 6904 poll_threads(); 6905 6906 /* cluster0: [ F0F0 AAAA | AAAA 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_aa, 8 * 512) == 0); 6912 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6913 6914 /* Verify write across multiple clusters */ 6915 6916 iov[0].iov_base = payload_ff; 6917 iov[0].iov_len = 8 * 512; 6918 spdk_blob_io_writev(blob, channel, iov, 1, 28, 8, blob_op_complete, NULL); 6919 poll_threads(); 6920 6921 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6922 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6923 6924 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6925 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6926 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6927 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6928 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6929 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6930 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6931 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 16 * 512) == 0); 6932 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6933 6934 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6935 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 6936 6937 /* Verify write to second cluster */ 6938 6939 iov[0].iov_base = payload_ff; 6940 iov[0].iov_len = 2 * 512; 6941 spdk_blob_io_writev(blob, channel, iov, 1, 32 + 12, 2, blob_op_complete, NULL); 6942 poll_threads(); 6943 6944 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6945 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6946 6947 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6948 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 6949 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6950 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6951 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6952 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6953 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6954 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6955 6956 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6957 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 6958 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 6959 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 6960 } 6961 6962 static void 6963 test_iov_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6964 { 6965 uint8_t payload_read[64 * 512]; 6966 uint8_t payload_ff[64 * 512]; 6967 uint8_t payload_aa[64 * 512]; 6968 uint8_t payload_00[64 * 512]; 6969 struct iovec iov[4]; 6970 6971 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6972 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6973 memset(payload_00, 0x00, sizeof(payload_00)); 6974 6975 /* Read only first io unit */ 6976 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6977 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6978 * payload_read: F000 0000 | 0000 0000 ... */ 6979 memset(payload_read, 0x00, sizeof(payload_read)); 6980 iov[0].iov_base = payload_read; 6981 iov[0].iov_len = 1 * 512; 6982 spdk_blob_io_readv(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 6983 poll_threads(); 6984 6985 CU_ASSERT(g_bserrno == 0); 6986 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6987 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 6988 6989 /* Read four io_units starting from offset = 2 6990 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6991 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6992 * payload_read: F0AA 0000 | 0000 0000 ... */ 6993 6994 memset(payload_read, 0x00, sizeof(payload_read)); 6995 iov[0].iov_base = payload_read; 6996 iov[0].iov_len = 4 * 512; 6997 spdk_blob_io_readv(blob, channel, iov, 1, 2, 4, blob_op_complete, NULL); 6998 poll_threads(); 6999 CU_ASSERT(g_bserrno == 0); 7000 7001 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 7002 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 7003 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 7004 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 7005 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 7006 7007 /* Read eight io_units across multiple pages 7008 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 7009 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 7010 * payload_read: AAAA AAAA | 0000 0000 ... */ 7011 memset(payload_read, 0x00, sizeof(payload_read)); 7012 iov[0].iov_base = payload_read; 7013 iov[0].iov_len = 4 * 512; 7014 iov[1].iov_base = payload_read + 4 * 512; 7015 iov[1].iov_len = 4 * 512; 7016 spdk_blob_io_readv(blob, channel, iov, 2, 4, 8, blob_op_complete, NULL); 7017 poll_threads(); 7018 CU_ASSERT(g_bserrno == 0); 7019 7020 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 7021 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 7022 7023 /* Read eight io_units across multiple clusters 7024 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 7025 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 7026 * payload_read: FFFF FFFF | 0000 0000 ... */ 7027 memset(payload_read, 0x00, sizeof(payload_read)); 7028 iov[0].iov_base = payload_read; 7029 iov[0].iov_len = 2 * 512; 7030 iov[1].iov_base = payload_read + 2 * 512; 7031 iov[1].iov_len = 2 * 512; 7032 iov[2].iov_base = payload_read + 4 * 512; 7033 iov[2].iov_len = 2 * 512; 7034 iov[3].iov_base = payload_read + 6 * 512; 7035 iov[3].iov_len = 2 * 512; 7036 spdk_blob_io_readv(blob, channel, iov, 4, 28, 8, blob_op_complete, NULL); 7037 poll_threads(); 7038 CU_ASSERT(g_bserrno == 0); 7039 7040 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 7041 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 7042 7043 /* Read four io_units from second cluster 7044 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7045 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 7046 * payload_read: 00FF 0000 | 0000 0000 ... */ 7047 memset(payload_read, 0x00, sizeof(payload_read)); 7048 iov[0].iov_base = payload_read; 7049 iov[0].iov_len = 1 * 512; 7050 iov[1].iov_base = payload_read + 1 * 512; 7051 iov[1].iov_len = 3 * 512; 7052 spdk_blob_io_readv(blob, channel, iov, 2, 32 + 10, 4, blob_op_complete, NULL); 7053 poll_threads(); 7054 CU_ASSERT(g_bserrno == 0); 7055 7056 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 7057 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 7058 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 7059 7060 /* Read second cluster 7061 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7062 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 7063 * payload_read: FFFF 0000 | 0000 FF00 ... */ 7064 memset(payload_read, 0x00, sizeof(payload_read)); 7065 iov[0].iov_base = payload_read; 7066 iov[0].iov_len = 1 * 512; 7067 iov[1].iov_base = payload_read + 1 * 512; 7068 iov[1].iov_len = 2 * 512; 7069 iov[2].iov_base = payload_read + 3 * 512; 7070 iov[2].iov_len = 4 * 512; 7071 iov[3].iov_base = payload_read + 7 * 512; 7072 iov[3].iov_len = 25 * 512; 7073 spdk_blob_io_readv(blob, channel, iov, 4, 32, 32, blob_op_complete, NULL); 7074 poll_threads(); 7075 CU_ASSERT(g_bserrno == 0); 7076 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 7077 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 7078 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 7079 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 7080 7081 /* Read whole two clusters 7082 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 7083 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 7084 memset(payload_read, 0x00, sizeof(payload_read)); 7085 iov[0].iov_base = payload_read; 7086 iov[0].iov_len = 1 * 512; 7087 iov[1].iov_base = payload_read + 1 * 512; 7088 iov[1].iov_len = 8 * 512; 7089 iov[2].iov_base = payload_read + 9 * 512; 7090 iov[2].iov_len = 16 * 512; 7091 iov[3].iov_base = payload_read + 25 * 512; 7092 iov[3].iov_len = 39 * 512; 7093 spdk_blob_io_readv(blob, channel, iov, 4, 0, 64, blob_op_complete, NULL); 7094 poll_threads(); 7095 CU_ASSERT(g_bserrno == 0); 7096 7097 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 7098 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 7099 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 7100 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 7101 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 7102 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 7103 7104 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 7105 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 7106 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 7107 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 7108 } 7109 7110 static void 7111 blob_io_unit(void) 7112 { 7113 struct spdk_bs_opts bsopts; 7114 struct spdk_blob_opts opts; 7115 struct spdk_blob_store *bs; 7116 struct spdk_bs_dev *dev; 7117 struct spdk_blob *blob, *snapshot, *clone; 7118 spdk_blob_id blobid; 7119 struct spdk_io_channel *channel; 7120 7121 /* Create dev with 512 bytes io unit size */ 7122 7123 spdk_bs_opts_init(&bsopts); 7124 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 7125 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 7126 7127 /* Try to initialize a new blob store with unsupported io_unit */ 7128 dev = init_dev(); 7129 dev->blocklen = 512; 7130 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 7131 7132 /* Initialize a new blob store */ 7133 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 7134 poll_threads(); 7135 CU_ASSERT(g_bserrno == 0); 7136 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7137 bs = g_bs; 7138 7139 CU_ASSERT(spdk_bs_get_io_unit_size(bs) == 512); 7140 channel = spdk_bs_alloc_io_channel(bs); 7141 7142 /* Create thick provisioned blob */ 7143 ut_spdk_blob_opts_init(&opts); 7144 opts.thin_provision = false; 7145 opts.num_clusters = 32; 7146 7147 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 7148 poll_threads(); 7149 7150 CU_ASSERT(g_bserrno == 0); 7151 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7152 blobid = g_blobid; 7153 7154 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7155 poll_threads(); 7156 CU_ASSERT(g_bserrno == 0); 7157 CU_ASSERT(g_blob != NULL); 7158 blob = g_blob; 7159 7160 test_io_write(dev, blob, channel); 7161 test_io_read(dev, blob, channel); 7162 test_io_zeroes(dev, blob, channel); 7163 7164 test_iov_write(dev, blob, channel); 7165 test_iov_read(dev, blob, channel); 7166 7167 test_io_unmap(dev, blob, channel); 7168 7169 spdk_blob_close(blob, blob_op_complete, NULL); 7170 poll_threads(); 7171 CU_ASSERT(g_bserrno == 0); 7172 blob = NULL; 7173 g_blob = NULL; 7174 7175 /* Create thin provisioned blob */ 7176 7177 ut_spdk_blob_opts_init(&opts); 7178 opts.thin_provision = true; 7179 opts.num_clusters = 32; 7180 7181 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 7182 poll_threads(); 7183 CU_ASSERT(g_bserrno == 0); 7184 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7185 blobid = g_blobid; 7186 7187 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7188 poll_threads(); 7189 CU_ASSERT(g_bserrno == 0); 7190 CU_ASSERT(g_blob != NULL); 7191 blob = g_blob; 7192 7193 test_io_write(dev, blob, channel); 7194 test_io_read(dev, blob, channel); 7195 7196 test_io_zeroes(dev, blob, channel); 7197 7198 test_iov_write(dev, blob, channel); 7199 test_iov_read(dev, blob, channel); 7200 7201 /* Create snapshot */ 7202 7203 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 7204 poll_threads(); 7205 CU_ASSERT(g_bserrno == 0); 7206 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7207 blobid = g_blobid; 7208 7209 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7210 poll_threads(); 7211 CU_ASSERT(g_bserrno == 0); 7212 CU_ASSERT(g_blob != NULL); 7213 snapshot = g_blob; 7214 7215 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 7216 poll_threads(); 7217 CU_ASSERT(g_bserrno == 0); 7218 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7219 blobid = g_blobid; 7220 7221 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7222 poll_threads(); 7223 CU_ASSERT(g_bserrno == 0); 7224 CU_ASSERT(g_blob != NULL); 7225 clone = g_blob; 7226 7227 test_io_read(dev, blob, channel); 7228 test_io_read(dev, snapshot, channel); 7229 test_io_read(dev, clone, channel); 7230 7231 test_iov_read(dev, blob, channel); 7232 test_iov_read(dev, snapshot, channel); 7233 test_iov_read(dev, clone, channel); 7234 7235 /* Inflate clone */ 7236 7237 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 7238 poll_threads(); 7239 7240 CU_ASSERT(g_bserrno == 0); 7241 7242 test_io_read(dev, clone, channel); 7243 7244 test_io_unmap(dev, clone, channel); 7245 7246 test_iov_write(dev, clone, channel); 7247 test_iov_read(dev, clone, channel); 7248 7249 spdk_blob_close(blob, blob_op_complete, NULL); 7250 spdk_blob_close(snapshot, blob_op_complete, NULL); 7251 spdk_blob_close(clone, blob_op_complete, NULL); 7252 poll_threads(); 7253 CU_ASSERT(g_bserrno == 0); 7254 blob = NULL; 7255 g_blob = NULL; 7256 7257 spdk_bs_free_io_channel(channel); 7258 poll_threads(); 7259 7260 /* Unload the blob store */ 7261 spdk_bs_unload(bs, bs_op_complete, NULL); 7262 poll_threads(); 7263 CU_ASSERT(g_bserrno == 0); 7264 g_bs = NULL; 7265 g_blob = NULL; 7266 g_blobid = 0; 7267 } 7268 7269 static void 7270 blob_io_unit_compatiblity(void) 7271 { 7272 struct spdk_bs_opts bsopts; 7273 struct spdk_blob_store *bs; 7274 struct spdk_bs_dev *dev; 7275 struct spdk_bs_super_block *super; 7276 7277 /* Create dev with 512 bytes io unit size */ 7278 7279 spdk_bs_opts_init(&bsopts); 7280 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 7281 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 7282 7283 /* Try to initialize a new blob store with unsupported io_unit */ 7284 dev = init_dev(); 7285 dev->blocklen = 512; 7286 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 7287 7288 /* Initialize a new blob store */ 7289 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 7290 poll_threads(); 7291 CU_ASSERT(g_bserrno == 0); 7292 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7293 bs = g_bs; 7294 7295 CU_ASSERT(spdk_bs_get_io_unit_size(bs) == 512); 7296 7297 /* Unload the blob store */ 7298 spdk_bs_unload(bs, bs_op_complete, NULL); 7299 poll_threads(); 7300 CU_ASSERT(g_bserrno == 0); 7301 7302 /* Modify super block to behave like older version. 7303 * Check if loaded io unit size equals SPDK_BS_PAGE_SIZE */ 7304 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 7305 super->io_unit_size = 0; 7306 super->crc = _spdk_blob_md_page_calc_crc(super); 7307 7308 dev = init_dev(); 7309 dev->blocklen = 512; 7310 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 7311 7312 spdk_bs_load(dev, &bsopts, bs_op_with_handle_complete, NULL); 7313 poll_threads(); 7314 CU_ASSERT(g_bserrno == 0); 7315 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7316 bs = g_bs; 7317 7318 CU_ASSERT(spdk_bs_get_io_unit_size(bs) == SPDK_BS_PAGE_SIZE); 7319 7320 /* Unload the blob store */ 7321 spdk_bs_unload(bs, bs_op_complete, NULL); 7322 poll_threads(); 7323 CU_ASSERT(g_bserrno == 0); 7324 7325 g_bs = NULL; 7326 g_blob = NULL; 7327 g_blobid = 0; 7328 } 7329 7330 static void 7331 blob_simultaneous_operations(void) 7332 { 7333 struct spdk_blob_store *bs; 7334 struct spdk_bs_dev *dev; 7335 struct spdk_blob_opts opts; 7336 struct spdk_blob *blob, *snapshot; 7337 spdk_blob_id blobid, snapshotid; 7338 struct spdk_io_channel *channel; 7339 7340 dev = init_dev(); 7341 7342 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 7343 poll_threads(); 7344 CU_ASSERT(g_bserrno == 0); 7345 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7346 bs = g_bs; 7347 7348 channel = spdk_bs_alloc_io_channel(bs); 7349 SPDK_CU_ASSERT_FATAL(channel != NULL); 7350 7351 ut_spdk_blob_opts_init(&opts); 7352 opts.num_clusters = 10; 7353 7354 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 7355 poll_threads(); 7356 CU_ASSERT(g_bserrno == 0); 7357 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7358 blobid = g_blobid; 7359 7360 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7361 poll_threads(); 7362 CU_ASSERT(g_bserrno == 0); 7363 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7364 blob = g_blob; 7365 7366 /* Create snapshot and try to remove blob in the same time: 7367 * - snapshot should be created successfully 7368 * - delete operation should fail w -EBUSY */ 7369 CU_ASSERT(blob->locked_operation_in_progress == false); 7370 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 7371 CU_ASSERT(blob->locked_operation_in_progress == true); 7372 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7373 CU_ASSERT(blob->locked_operation_in_progress == true); 7374 /* Deletion failure */ 7375 CU_ASSERT(g_bserrno == -EBUSY); 7376 poll_threads(); 7377 CU_ASSERT(blob->locked_operation_in_progress == false); 7378 /* Snapshot creation success */ 7379 CU_ASSERT(g_bserrno == 0); 7380 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7381 7382 snapshotid = g_blobid; 7383 7384 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 7385 poll_threads(); 7386 CU_ASSERT(g_bserrno == 0); 7387 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7388 snapshot = g_blob; 7389 7390 /* Inflate blob and try to remove blob in the same time: 7391 * - blob should be inflated successfully 7392 * - delete operation should fail w -EBUSY */ 7393 CU_ASSERT(blob->locked_operation_in_progress == false); 7394 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 7395 CU_ASSERT(blob->locked_operation_in_progress == true); 7396 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7397 CU_ASSERT(blob->locked_operation_in_progress == true); 7398 /* Deletion failure */ 7399 CU_ASSERT(g_bserrno == -EBUSY); 7400 poll_threads(); 7401 CU_ASSERT(blob->locked_operation_in_progress == false); 7402 /* Inflation success */ 7403 CU_ASSERT(g_bserrno == 0); 7404 7405 /* Clone snapshot and try to remove snapshot in the same time: 7406 * - snapshot should be cloned successfully 7407 * - delete operation should fail w -EBUSY */ 7408 CU_ASSERT(blob->locked_operation_in_progress == false); 7409 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 7410 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 7411 /* Deletion failure */ 7412 CU_ASSERT(g_bserrno == -EBUSY); 7413 poll_threads(); 7414 CU_ASSERT(blob->locked_operation_in_progress == false); 7415 /* Clone created */ 7416 CU_ASSERT(g_bserrno == 0); 7417 7418 /* Resize blob and try to remove blob in the same time: 7419 * - blob should be resized successfully 7420 * - delete operation should fail w -EBUSY */ 7421 CU_ASSERT(blob->locked_operation_in_progress == false); 7422 spdk_blob_resize(blob, 50, blob_op_complete, NULL); 7423 CU_ASSERT(blob->locked_operation_in_progress == true); 7424 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7425 CU_ASSERT(blob->locked_operation_in_progress == true); 7426 /* Deletion failure */ 7427 CU_ASSERT(g_bserrno == -EBUSY); 7428 poll_threads(); 7429 CU_ASSERT(blob->locked_operation_in_progress == false); 7430 /* Blob resized successfully */ 7431 CU_ASSERT(g_bserrno == 0); 7432 7433 /* Issue two consecutive blob syncs, neither should fail. 7434 * Force sync to actually occur by marking blob dirty each time. 7435 * Execution of sync should not be enough to complete the operation, 7436 * since disk I/O is required to complete it. */ 7437 g_bserrno = -1; 7438 7439 blob->state = SPDK_BLOB_STATE_DIRTY; 7440 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7441 SPDK_CU_ASSERT_FATAL(g_bserrno == -1); 7442 7443 blob->state = SPDK_BLOB_STATE_DIRTY; 7444 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7445 SPDK_CU_ASSERT_FATAL(g_bserrno == -1); 7446 7447 uint32_t completions = 0; 7448 while (completions < 2) { 7449 SPDK_CU_ASSERT_FATAL(poll_thread_times(0, 1)); 7450 if (g_bserrno == 0) { 7451 g_bserrno = -1; 7452 completions++; 7453 } 7454 /* Never should the g_bserrno be other than -1. 7455 * It would mean that either of syncs failed. */ 7456 SPDK_CU_ASSERT_FATAL(g_bserrno == -1); 7457 } 7458 7459 spdk_blob_close(blob, blob_op_complete, NULL); 7460 poll_threads(); 7461 CU_ASSERT(g_bserrno == 0); 7462 7463 spdk_blob_close(snapshot, blob_op_complete, NULL); 7464 poll_threads(); 7465 CU_ASSERT(g_bserrno == 0); 7466 7467 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7468 poll_threads(); 7469 CU_ASSERT(g_bserrno == 0); 7470 7471 spdk_bs_unload(bs, bs_op_complete, NULL); 7472 poll_threads(); 7473 CU_ASSERT(g_bserrno == 0); 7474 g_bs = NULL; 7475 7476 spdk_bs_free_io_channel(channel); 7477 poll_threads(); 7478 } 7479 7480 static void 7481 blob_persist(void) 7482 { 7483 struct spdk_blob_store *bs; 7484 struct spdk_bs_dev *dev; 7485 struct spdk_blob_opts opts; 7486 struct spdk_blob *blob; 7487 spdk_blob_id blobid; 7488 struct spdk_io_channel *channel; 7489 char *xattr; 7490 size_t xattr_length; 7491 int rc; 7492 uint32_t page_count_clear, page_count_xattr; 7493 uint64_t poller_iterations; 7494 bool run_poller; 7495 7496 dev = init_dev(); 7497 7498 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 7499 poll_threads(); 7500 CU_ASSERT(g_bserrno == 0); 7501 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7502 bs = g_bs; 7503 7504 channel = spdk_bs_alloc_io_channel(bs); 7505 SPDK_CU_ASSERT_FATAL(channel != NULL); 7506 7507 ut_spdk_blob_opts_init(&opts); 7508 opts.num_clusters = 10; 7509 7510 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 7511 poll_threads(); 7512 CU_ASSERT(g_bserrno == 0); 7513 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7514 blobid = g_blobid; 7515 7516 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7517 poll_threads(); 7518 CU_ASSERT(g_bserrno == 0); 7519 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7520 blob = g_blob; 7521 7522 /* Save the amount of md pages used after creation of a blob. 7523 * This should be consistent after removing xattr. */ 7524 page_count_clear = spdk_bit_array_count_set(bs->used_md_pages); 7525 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_clear); 7526 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_clear); 7527 7528 /* Add xattr with maximum length of descriptor to exceed single metadata page. */ 7529 xattr_length = SPDK_BS_MAX_DESC_SIZE - sizeof(struct spdk_blob_md_descriptor_xattr) - 7530 strlen("large_xattr"); 7531 xattr = calloc(xattr_length, sizeof(char)); 7532 SPDK_CU_ASSERT_FATAL(xattr != NULL); 7533 7534 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); 7535 SPDK_CU_ASSERT_FATAL(rc == 0); 7536 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7537 poll_threads(); 7538 SPDK_CU_ASSERT_FATAL(g_bserrno == 0); 7539 7540 /* Save the amount of md pages used after adding the large xattr */ 7541 page_count_xattr = spdk_bit_array_count_set(bs->used_md_pages); 7542 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_xattr); 7543 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_xattr); 7544 7545 /* Add xattr to a blob and sync it. While sync is occuring, remove the xattr and sync again. 7546 * Interrupt the first sync after increasing number of poller iterations, until it succeeds. 7547 * Expectation is that after second sync completes no xattr is saved in metadata. */ 7548 poller_iterations = 1; 7549 run_poller = true; 7550 while (run_poller) { 7551 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); 7552 SPDK_CU_ASSERT_FATAL(rc == 0); 7553 g_bserrno = -1; 7554 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7555 poll_thread_times(0, poller_iterations); 7556 if (g_bserrno == 0) { 7557 /* Poller iteration count was high enough for first sync to complete. 7558 * Verify that blob takes up enough of md_pages to store the xattr. */ 7559 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_xattr); 7560 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_xattr); 7561 SPDK_CU_ASSERT_FATAL(spdk_bit_array_count_set(bs->used_md_pages) == page_count_xattr); 7562 run_poller = false; 7563 } 7564 rc = spdk_blob_remove_xattr(blob, "large_xattr"); 7565 SPDK_CU_ASSERT_FATAL(rc == 0); 7566 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7567 poll_threads(); 7568 SPDK_CU_ASSERT_FATAL(g_bserrno == 0); 7569 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_clear); 7570 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_clear); 7571 SPDK_CU_ASSERT_FATAL(spdk_bit_array_count_set(bs->used_md_pages) == page_count_clear); 7572 7573 /* Reload bs and re-open blob to verify that xattr was not persisted. */ 7574 spdk_blob_close(blob, blob_op_complete, NULL); 7575 poll_threads(); 7576 CU_ASSERT(g_bserrno == 0); 7577 7578 ut_bs_reload(&bs, NULL); 7579 7580 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7581 poll_threads(); 7582 CU_ASSERT(g_bserrno == 0); 7583 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7584 blob = g_blob; 7585 7586 rc = spdk_blob_get_xattr_value(blob, "large_xattr", (const void **)&xattr, &xattr_length); 7587 SPDK_CU_ASSERT_FATAL(rc == -ENOENT); 7588 7589 poller_iterations++; 7590 /* Stop at high iteration count to prevent infinite loop. 7591 * This value should be enough for first md sync to complete in any case. */ 7592 SPDK_CU_ASSERT_FATAL(poller_iterations < 50); 7593 } 7594 7595 free(xattr); 7596 7597 spdk_blob_close(blob, blob_op_complete, NULL); 7598 poll_threads(); 7599 CU_ASSERT(g_bserrno == 0); 7600 7601 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7602 poll_threads(); 7603 CU_ASSERT(g_bserrno == 0); 7604 7605 spdk_bs_unload(bs, bs_op_complete, NULL); 7606 poll_threads(); 7607 CU_ASSERT(g_bserrno == 0); 7608 g_bs = NULL; 7609 7610 spdk_bs_free_io_channel(channel); 7611 poll_threads(); 7612 } 7613 7614 int main(int argc, char **argv) 7615 { 7616 CU_pSuite suite = NULL; 7617 unsigned int num_failures; 7618 7619 CU_set_error_action(CUEA_ABORT); 7620 CU_initialize_registry(); 7621 7622 suite = CU_add_suite("blob", NULL, NULL); 7623 7624 CU_ADD_TEST(suite, blob_init); 7625 CU_ADD_TEST(suite, blob_open); 7626 CU_ADD_TEST(suite, blob_create); 7627 CU_ADD_TEST(suite, blob_create_internal); 7628 CU_ADD_TEST(suite, blob_thin_provision); 7629 CU_ADD_TEST(suite, blob_snapshot); 7630 CU_ADD_TEST(suite, blob_clone); 7631 CU_ADD_TEST(suite, blob_inflate); 7632 CU_ADD_TEST(suite, blob_delete); 7633 CU_ADD_TEST(suite, blob_resize); 7634 CU_ADD_TEST(suite, blob_read_only); 7635 CU_ADD_TEST(suite, channel_ops); 7636 CU_ADD_TEST(suite, blob_super); 7637 CU_ADD_TEST(suite, blob_write); 7638 CU_ADD_TEST(suite, blob_read); 7639 CU_ADD_TEST(suite, blob_rw_verify); 7640 CU_ADD_TEST(suite, blob_rw_verify_iov); 7641 CU_ADD_TEST(suite, blob_rw_verify_iov_nomem); 7642 CU_ADD_TEST(suite, blob_rw_iov_read_only); 7643 CU_ADD_TEST(suite, blob_unmap); 7644 CU_ADD_TEST(suite, blob_iter); 7645 CU_ADD_TEST(suite, blob_xattr); 7646 CU_ADD_TEST(suite, bs_load); 7647 CU_ADD_TEST(suite, bs_load_pending_removal); 7648 CU_ADD_TEST(suite, bs_load_custom_cluster_size); 7649 CU_ADD_TEST(suite, bs_unload); 7650 CU_ADD_TEST(suite, bs_cluster_sz); 7651 CU_ADD_TEST(suite, bs_usable_clusters); 7652 CU_ADD_TEST(suite, bs_resize_md); 7653 CU_ADD_TEST(suite, bs_destroy); 7654 CU_ADD_TEST(suite, bs_type); 7655 CU_ADD_TEST(suite, bs_super_block); 7656 CU_ADD_TEST(suite, blob_serialize); 7657 CU_ADD_TEST(suite, blob_crc); 7658 CU_ADD_TEST(suite, super_block_crc); 7659 CU_ADD_TEST(suite, blob_dirty_shutdown); 7660 CU_ADD_TEST(suite, blob_flags); 7661 CU_ADD_TEST(suite, bs_version); 7662 CU_ADD_TEST(suite, blob_set_xattrs); 7663 CU_ADD_TEST(suite, blob_thin_prov_alloc); 7664 CU_ADD_TEST(suite, blob_insert_cluster_msg); 7665 CU_ADD_TEST(suite, blob_thin_prov_rw); 7666 CU_ADD_TEST(suite, blob_thin_prov_rle); 7667 CU_ADD_TEST(suite, blob_thin_prov_rw_iov); 7668 CU_ADD_TEST(suite, bs_load_iter); 7669 CU_ADD_TEST(suite, blob_snapshot_rw); 7670 CU_ADD_TEST(suite, blob_snapshot_rw_iov); 7671 CU_ADD_TEST(suite, blob_relations); 7672 CU_ADD_TEST(suite, blob_relations2); 7673 CU_ADD_TEST(suite, blob_delete_snapshot_power_failure); 7674 CU_ADD_TEST(suite, blob_create_snapshot_power_failure); 7675 CU_ADD_TEST(suite, blob_inflate_rw); 7676 CU_ADD_TEST(suite, blob_snapshot_freeze_io); 7677 CU_ADD_TEST(suite, blob_operation_split_rw); 7678 CU_ADD_TEST(suite, blob_operation_split_rw_iov); 7679 CU_ADD_TEST(suite, blob_io_unit); 7680 CU_ADD_TEST(suite, blob_io_unit_compatiblity); 7681 CU_ADD_TEST(suite, blob_simultaneous_operations); 7682 CU_ADD_TEST(suite, blob_persist); 7683 7684 allocate_threads(2); 7685 set_thread(0); 7686 7687 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 7688 7689 CU_basic_set_mode(CU_BRM_VERBOSE); 7690 g_use_extent_table = false; 7691 CU_basic_run_tests(); 7692 num_failures = CU_get_number_of_failures(); 7693 g_use_extent_table = true; 7694 CU_basic_run_tests(); 7695 num_failures += CU_get_number_of_failures(); 7696 CU_cleanup_registry(); 7697 7698 free(g_dev_buffer); 7699 7700 free_threads(); 7701 7702 return num_failures; 7703 } 7704