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