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 spdk_bs_free_io_channel(channel_thread1); 4776 spdk_bs_free_io_channel(channel); 4777 poll_threads(); 4778 4779 /* Unload the blob store */ 4780 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4781 poll_threads(); 4782 CU_ASSERT(g_bserrno == 0); 4783 g_bs = NULL; 4784 g_blob = NULL; 4785 g_blobid = 0; 4786 } 4787 4788 static void 4789 blob_thin_prov_rle(void) 4790 { 4791 static const uint8_t zero[10 * 4096] = { 0 }; 4792 struct spdk_blob_store *bs; 4793 struct spdk_bs_dev *dev; 4794 struct spdk_blob *blob; 4795 struct spdk_io_channel *channel; 4796 struct spdk_blob_opts opts; 4797 spdk_blob_id blobid; 4798 uint64_t free_clusters; 4799 uint64_t page_size; 4800 uint8_t payload_read[10 * 4096]; 4801 uint8_t payload_write[10 * 4096]; 4802 uint64_t write_bytes; 4803 uint64_t read_bytes; 4804 uint64_t io_unit; 4805 4806 dev = init_dev(); 4807 4808 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4809 poll_threads(); 4810 CU_ASSERT(g_bserrno == 0); 4811 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4812 bs = g_bs; 4813 free_clusters = spdk_bs_free_cluster_count(bs); 4814 page_size = spdk_bs_get_page_size(bs); 4815 4816 ut_spdk_blob_opts_init(&opts); 4817 opts.thin_provision = true; 4818 opts.num_clusters = 5; 4819 4820 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4821 poll_threads(); 4822 CU_ASSERT(g_bserrno == 0); 4823 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4824 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4825 blobid = g_blobid; 4826 4827 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4828 poll_threads(); 4829 CU_ASSERT(g_bserrno == 0); 4830 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4831 blob = g_blob; 4832 4833 channel = spdk_bs_alloc_io_channel(bs); 4834 CU_ASSERT(channel != NULL); 4835 4836 /* Target specifically second cluster in a blob as first allocation */ 4837 io_unit = _spdk_bs_cluster_to_page(bs, 1) * _spdk_bs_io_unit_per_page(bs); 4838 4839 /* Payload should be all zeros from unallocated clusters */ 4840 memset(payload_read, 0xFF, sizeof(payload_read)); 4841 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL); 4842 poll_threads(); 4843 CU_ASSERT(g_bserrno == 0); 4844 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4845 4846 write_bytes = g_dev_write_bytes; 4847 read_bytes = g_dev_read_bytes; 4848 4849 /* Issue write to second cluster in a blob */ 4850 memset(payload_write, 0xE5, sizeof(payload_write)); 4851 spdk_blob_io_write(blob, channel, payload_write, io_unit, 10, blob_op_complete, NULL); 4852 poll_threads(); 4853 CU_ASSERT(g_bserrno == 0); 4854 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4855 /* For thin-provisioned blob we need to write 10 pages plus one page metadata and 4856 * read 0 bytes */ 4857 if (g_use_extent_table) { 4858 /* Add one more page for EXTENT_PAGE write */ 4859 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 12); 4860 } else { 4861 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11); 4862 } 4863 CU_ASSERT(g_dev_read_bytes - read_bytes == 0); 4864 4865 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL); 4866 poll_threads(); 4867 CU_ASSERT(g_bserrno == 0); 4868 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4869 4870 spdk_bs_free_io_channel(channel); 4871 poll_threads(); 4872 4873 spdk_blob_close(blob, blob_op_complete, NULL); 4874 poll_threads(); 4875 CU_ASSERT(g_bserrno == 0); 4876 4877 /* Unload the blob store */ 4878 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4879 poll_threads(); 4880 CU_ASSERT(g_bserrno == 0); 4881 g_bs = NULL; 4882 g_blob = NULL; 4883 g_blobid = 0; 4884 4885 /* Load an existing blob store */ 4886 dev = init_dev(); 4887 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4888 poll_threads(); 4889 CU_ASSERT(g_bserrno == 0); 4890 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4891 4892 bs = g_bs; 4893 4894 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 4895 poll_threads(); 4896 CU_ASSERT(g_bserrno == 0); 4897 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4898 blob = g_blob; 4899 4900 channel = spdk_bs_alloc_io_channel(bs); 4901 CU_ASSERT(channel != NULL); 4902 4903 /* Read second cluster after blob reload to confirm data written */ 4904 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL); 4905 poll_threads(); 4906 CU_ASSERT(g_bserrno == 0); 4907 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4908 4909 spdk_bs_free_io_channel(channel); 4910 poll_threads(); 4911 4912 spdk_blob_close(blob, blob_op_complete, NULL); 4913 poll_threads(); 4914 CU_ASSERT(g_bserrno == 0); 4915 4916 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4917 poll_threads(); 4918 CU_ASSERT(g_bserrno == 0); 4919 4920 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4921 poll_threads(); 4922 CU_ASSERT(g_bserrno == 0); 4923 g_bs = NULL; 4924 } 4925 4926 static void 4927 blob_thin_prov_rw_iov(void) 4928 { 4929 static const uint8_t zero[10 * 4096] = { 0 }; 4930 struct spdk_blob_store *bs; 4931 struct spdk_bs_dev *dev; 4932 struct spdk_blob *blob; 4933 struct spdk_io_channel *channel; 4934 struct spdk_blob_opts opts; 4935 spdk_blob_id blobid; 4936 uint64_t free_clusters; 4937 uint8_t payload_read[10 * 4096]; 4938 uint8_t payload_write[10 * 4096]; 4939 struct iovec iov_read[3]; 4940 struct iovec iov_write[3]; 4941 4942 dev = init_dev(); 4943 4944 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4945 poll_threads(); 4946 CU_ASSERT(g_bserrno == 0); 4947 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4948 bs = g_bs; 4949 free_clusters = spdk_bs_free_cluster_count(bs); 4950 4951 channel = spdk_bs_alloc_io_channel(bs); 4952 CU_ASSERT(channel != NULL); 4953 4954 ut_spdk_blob_opts_init(&opts); 4955 opts.thin_provision = true; 4956 4957 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4958 poll_threads(); 4959 CU_ASSERT(g_bserrno == 0); 4960 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4961 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4962 blobid = g_blobid; 4963 4964 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4965 poll_threads(); 4966 CU_ASSERT(g_bserrno == 0); 4967 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4968 blob = g_blob; 4969 4970 CU_ASSERT(blob->active.num_clusters == 0); 4971 4972 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4973 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4974 poll_threads(); 4975 CU_ASSERT(g_bserrno == 0); 4976 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4977 CU_ASSERT(blob->active.num_clusters == 5); 4978 4979 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4980 poll_threads(); 4981 CU_ASSERT(g_bserrno == 0); 4982 /* Sync must not change anything */ 4983 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4984 CU_ASSERT(blob->active.num_clusters == 5); 4985 4986 /* Payload should be all zeros from unallocated clusters */ 4987 memset(payload_read, 0xAA, sizeof(payload_read)); 4988 iov_read[0].iov_base = payload_read; 4989 iov_read[0].iov_len = 3 * 4096; 4990 iov_read[1].iov_base = payload_read + 3 * 4096; 4991 iov_read[1].iov_len = 4 * 4096; 4992 iov_read[2].iov_base = payload_read + 7 * 4096; 4993 iov_read[2].iov_len = 3 * 4096; 4994 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4995 poll_threads(); 4996 CU_ASSERT(g_bserrno == 0); 4997 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4998 4999 memset(payload_write, 0xE5, sizeof(payload_write)); 5000 iov_write[0].iov_base = payload_write; 5001 iov_write[0].iov_len = 1 * 4096; 5002 iov_write[1].iov_base = payload_write + 1 * 4096; 5003 iov_write[1].iov_len = 5 * 4096; 5004 iov_write[2].iov_base = payload_write + 6 * 4096; 5005 iov_write[2].iov_len = 4 * 4096; 5006 5007 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 5008 poll_threads(); 5009 CU_ASSERT(g_bserrno == 0); 5010 5011 memset(payload_read, 0xAA, sizeof(payload_read)); 5012 iov_read[0].iov_base = payload_read; 5013 iov_read[0].iov_len = 3 * 4096; 5014 iov_read[1].iov_base = payload_read + 3 * 4096; 5015 iov_read[1].iov_len = 4 * 4096; 5016 iov_read[2].iov_base = payload_read + 7 * 4096; 5017 iov_read[2].iov_len = 3 * 4096; 5018 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 5019 poll_threads(); 5020 CU_ASSERT(g_bserrno == 0); 5021 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 5022 5023 spdk_blob_close(blob, blob_op_complete, NULL); 5024 poll_threads(); 5025 CU_ASSERT(g_bserrno == 0); 5026 5027 spdk_bs_free_io_channel(channel); 5028 poll_threads(); 5029 5030 /* Unload the blob store */ 5031 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5032 poll_threads(); 5033 CU_ASSERT(g_bserrno == 0); 5034 g_bs = NULL; 5035 g_blob = NULL; 5036 g_blobid = 0; 5037 } 5038 5039 struct iter_ctx { 5040 int current_iter; 5041 spdk_blob_id blobid[4]; 5042 }; 5043 5044 static void 5045 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 5046 { 5047 struct iter_ctx *iter_ctx = arg; 5048 spdk_blob_id blobid; 5049 5050 CU_ASSERT(bserrno == 0); 5051 blobid = spdk_blob_get_id(blob); 5052 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 5053 } 5054 5055 static void 5056 bs_load_iter(void) 5057 { 5058 struct spdk_bs_dev *dev; 5059 struct iter_ctx iter_ctx = { 0 }; 5060 struct spdk_blob *blob; 5061 int i, rc; 5062 struct spdk_bs_opts opts; 5063 struct spdk_blob_opts blob_opts; 5064 5065 dev = init_dev(); 5066 spdk_bs_opts_init(&opts); 5067 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 5068 5069 /* Initialize a new blob store */ 5070 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 5071 poll_threads(); 5072 CU_ASSERT(g_bserrno == 0); 5073 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5074 5075 ut_spdk_blob_opts_init(&blob_opts); 5076 5077 for (i = 0; i < 4; i++) { 5078 g_bserrno = -1; 5079 g_blobid = SPDK_BLOBID_INVALID; 5080 spdk_bs_create_blob_ext(g_bs, &blob_opts, blob_op_with_id_complete, NULL); 5081 poll_threads(); 5082 CU_ASSERT(g_bserrno == 0); 5083 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5084 iter_ctx.blobid[i] = g_blobid; 5085 5086 g_bserrno = -1; 5087 g_blob = NULL; 5088 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 5089 poll_threads(); 5090 CU_ASSERT(g_bserrno == 0); 5091 CU_ASSERT(g_blob != NULL); 5092 blob = g_blob; 5093 5094 /* Just save the blobid as an xattr for testing purposes. */ 5095 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 5096 CU_ASSERT(rc == 0); 5097 5098 /* Resize the blob */ 5099 spdk_blob_resize(blob, i, blob_op_complete, NULL); 5100 poll_threads(); 5101 CU_ASSERT(g_bserrno == 0); 5102 5103 spdk_blob_close(blob, blob_op_complete, NULL); 5104 poll_threads(); 5105 CU_ASSERT(g_bserrno == 0); 5106 } 5107 5108 g_bserrno = -1; 5109 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5110 poll_threads(); 5111 CU_ASSERT(g_bserrno == 0); 5112 5113 dev = init_dev(); 5114 spdk_bs_opts_init(&opts); 5115 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 5116 opts.iter_cb_fn = test_iter; 5117 opts.iter_cb_arg = &iter_ctx; 5118 5119 /* Test blob iteration during load after a clean shutdown. */ 5120 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 5121 poll_threads(); 5122 CU_ASSERT(g_bserrno == 0); 5123 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5124 5125 /* Dirty shutdown */ 5126 _spdk_bs_free(g_bs); 5127 5128 dev = init_dev(); 5129 spdk_bs_opts_init(&opts); 5130 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 5131 opts.iter_cb_fn = test_iter; 5132 iter_ctx.current_iter = 0; 5133 opts.iter_cb_arg = &iter_ctx; 5134 5135 /* Test blob iteration during load after a dirty shutdown. */ 5136 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 5137 poll_threads(); 5138 CU_ASSERT(g_bserrno == 0); 5139 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5140 5141 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5142 poll_threads(); 5143 CU_ASSERT(g_bserrno == 0); 5144 g_bs = NULL; 5145 } 5146 5147 static void 5148 blob_snapshot_rw(void) 5149 { 5150 static const uint8_t zero[10 * 4096] = { 0 }; 5151 struct spdk_blob_store *bs; 5152 struct spdk_bs_dev *dev; 5153 struct spdk_blob *blob, *snapshot; 5154 struct spdk_io_channel *channel; 5155 struct spdk_blob_opts opts; 5156 spdk_blob_id blobid, snapshotid; 5157 uint64_t free_clusters; 5158 uint64_t cluster_size; 5159 uint64_t page_size; 5160 uint8_t payload_read[10 * 4096]; 5161 uint8_t payload_write[10 * 4096]; 5162 uint64_t write_bytes; 5163 uint64_t read_bytes; 5164 5165 dev = init_dev(); 5166 5167 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5168 poll_threads(); 5169 CU_ASSERT(g_bserrno == 0); 5170 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5171 bs = g_bs; 5172 free_clusters = spdk_bs_free_cluster_count(bs); 5173 cluster_size = spdk_bs_get_cluster_size(bs); 5174 page_size = spdk_bs_get_page_size(bs); 5175 5176 channel = spdk_bs_alloc_io_channel(bs); 5177 CU_ASSERT(channel != NULL); 5178 5179 ut_spdk_blob_opts_init(&opts); 5180 opts.thin_provision = true; 5181 opts.num_clusters = 5; 5182 5183 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5184 poll_threads(); 5185 CU_ASSERT(g_bserrno == 0); 5186 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5187 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5188 blobid = g_blobid; 5189 5190 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5191 poll_threads(); 5192 CU_ASSERT(g_bserrno == 0); 5193 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5194 blob = g_blob; 5195 5196 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5197 5198 memset(payload_read, 0xFF, sizeof(payload_read)); 5199 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 5200 poll_threads(); 5201 CU_ASSERT(g_bserrno == 0); 5202 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 5203 5204 memset(payload_write, 0xE5, sizeof(payload_write)); 5205 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 5206 poll_threads(); 5207 CU_ASSERT(g_bserrno == 0); 5208 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5209 5210 /* Create snapshot from blob */ 5211 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5212 poll_threads(); 5213 CU_ASSERT(g_bserrno == 0); 5214 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5215 snapshotid = g_blobid; 5216 5217 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5218 poll_threads(); 5219 CU_ASSERT(g_bserrno == 0); 5220 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5221 snapshot = g_blob; 5222 CU_ASSERT(snapshot->data_ro == true); 5223 CU_ASSERT(snapshot->md_ro == true); 5224 5225 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 5226 5227 write_bytes = g_dev_write_bytes; 5228 read_bytes = g_dev_read_bytes; 5229 5230 memset(payload_write, 0xAA, sizeof(payload_write)); 5231 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 5232 poll_threads(); 5233 CU_ASSERT(g_bserrno == 0); 5234 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5235 5236 /* For a clone we need to allocate and copy one cluster, update one page of metadata 5237 * and then write 10 pages of payload. 5238 */ 5239 if (g_use_extent_table) { 5240 /* Add one more page for EXTENT_PAGE write */ 5241 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 12 + cluster_size); 5242 } else { 5243 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11 + cluster_size); 5244 } 5245 CU_ASSERT(g_dev_read_bytes - read_bytes == cluster_size); 5246 5247 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 5248 poll_threads(); 5249 CU_ASSERT(g_bserrno == 0); 5250 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 5251 5252 /* Data on snapshot should not change after write to clone */ 5253 memset(payload_write, 0xE5, sizeof(payload_write)); 5254 spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL); 5255 poll_threads(); 5256 CU_ASSERT(g_bserrno == 0); 5257 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 5258 5259 spdk_blob_close(blob, blob_op_complete, NULL); 5260 poll_threads(); 5261 CU_ASSERT(g_bserrno == 0); 5262 5263 spdk_blob_close(snapshot, blob_op_complete, NULL); 5264 poll_threads(); 5265 CU_ASSERT(g_bserrno == 0); 5266 5267 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5268 poll_threads(); 5269 CU_ASSERT(g_bserrno == 0); 5270 5271 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5272 poll_threads(); 5273 CU_ASSERT(g_bserrno == 0); 5274 5275 spdk_bs_free_io_channel(channel); 5276 poll_threads(); 5277 5278 /* Unload the blob store */ 5279 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5280 poll_threads(); 5281 CU_ASSERT(g_bserrno == 0); 5282 g_bs = NULL; 5283 g_blob = NULL; 5284 g_blobid = 0; 5285 } 5286 5287 static void 5288 blob_snapshot_rw_iov(void) 5289 { 5290 static const uint8_t zero[10 * 4096] = { 0 }; 5291 struct spdk_blob_store *bs; 5292 struct spdk_bs_dev *dev; 5293 struct spdk_blob *blob, *snapshot; 5294 struct spdk_io_channel *channel; 5295 struct spdk_blob_opts opts; 5296 spdk_blob_id blobid, snapshotid; 5297 uint64_t free_clusters; 5298 uint8_t payload_read[10 * 4096]; 5299 uint8_t payload_write[10 * 4096]; 5300 struct iovec iov_read[3]; 5301 struct iovec iov_write[3]; 5302 5303 dev = init_dev(); 5304 5305 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5306 poll_threads(); 5307 CU_ASSERT(g_bserrno == 0); 5308 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5309 bs = g_bs; 5310 free_clusters = spdk_bs_free_cluster_count(bs); 5311 5312 channel = spdk_bs_alloc_io_channel(bs); 5313 CU_ASSERT(channel != NULL); 5314 5315 ut_spdk_blob_opts_init(&opts); 5316 opts.thin_provision = true; 5317 opts.num_clusters = 5; 5318 5319 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5320 poll_threads(); 5321 CU_ASSERT(g_bserrno == 0); 5322 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5323 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5324 blobid = g_blobid; 5325 5326 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5327 poll_threads(); 5328 CU_ASSERT(g_bserrno == 0); 5329 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5330 blob = g_blob; 5331 5332 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5333 5334 /* Create snapshot from blob */ 5335 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5336 poll_threads(); 5337 CU_ASSERT(g_bserrno == 0); 5338 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5339 snapshotid = g_blobid; 5340 5341 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5342 poll_threads(); 5343 CU_ASSERT(g_bserrno == 0); 5344 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5345 snapshot = g_blob; 5346 CU_ASSERT(snapshot->data_ro == true); 5347 CU_ASSERT(snapshot->md_ro == true); 5348 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 5349 5350 /* Payload should be all zeros from unallocated clusters */ 5351 memset(payload_read, 0xAA, sizeof(payload_read)); 5352 iov_read[0].iov_base = payload_read; 5353 iov_read[0].iov_len = 3 * 4096; 5354 iov_read[1].iov_base = payload_read + 3 * 4096; 5355 iov_read[1].iov_len = 4 * 4096; 5356 iov_read[2].iov_base = payload_read + 7 * 4096; 5357 iov_read[2].iov_len = 3 * 4096; 5358 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 5359 poll_threads(); 5360 CU_ASSERT(g_bserrno == 0); 5361 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 5362 5363 memset(payload_write, 0xE5, sizeof(payload_write)); 5364 iov_write[0].iov_base = payload_write; 5365 iov_write[0].iov_len = 1 * 4096; 5366 iov_write[1].iov_base = payload_write + 1 * 4096; 5367 iov_write[1].iov_len = 5 * 4096; 5368 iov_write[2].iov_base = payload_write + 6 * 4096; 5369 iov_write[2].iov_len = 4 * 4096; 5370 5371 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 5372 poll_threads(); 5373 CU_ASSERT(g_bserrno == 0); 5374 5375 memset(payload_read, 0xAA, sizeof(payload_read)); 5376 iov_read[0].iov_base = payload_read; 5377 iov_read[0].iov_len = 3 * 4096; 5378 iov_read[1].iov_base = payload_read + 3 * 4096; 5379 iov_read[1].iov_len = 4 * 4096; 5380 iov_read[2].iov_base = payload_read + 7 * 4096; 5381 iov_read[2].iov_len = 3 * 4096; 5382 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 5383 poll_threads(); 5384 CU_ASSERT(g_bserrno == 0); 5385 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 5386 5387 spdk_blob_close(blob, blob_op_complete, NULL); 5388 poll_threads(); 5389 CU_ASSERT(g_bserrno == 0); 5390 5391 spdk_blob_close(snapshot, blob_op_complete, NULL); 5392 poll_threads(); 5393 CU_ASSERT(g_bserrno == 0); 5394 5395 spdk_bs_free_io_channel(channel); 5396 poll_threads(); 5397 5398 /* Unload the blob store */ 5399 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5400 poll_threads(); 5401 CU_ASSERT(g_bserrno == 0); 5402 g_bs = NULL; 5403 g_blob = NULL; 5404 g_blobid = 0; 5405 } 5406 5407 /** 5408 * Inflate / decouple parent rw unit tests. 5409 * 5410 * -------------- 5411 * original blob: 0 1 2 3 4 5412 * ,---------+---------+---------+---------+---------. 5413 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 5414 * +---------+---------+---------+---------+---------+ 5415 * snapshot2 | - |yyyyyyyyy| - |yyyyyyyyy| - | 5416 * +---------+---------+---------+---------+---------+ 5417 * blob | - |zzzzzzzzz| - | - | - | 5418 * '---------+---------+---------+---------+---------' 5419 * . . . . . . 5420 * -------- . . . . . . 5421 * inflate: . . . . . . 5422 * ,---------+---------+---------+---------+---------. 5423 * blob |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000| 5424 * '---------+---------+---------+---------+---------' 5425 * 5426 * NOTE: needs to allocate 4 clusters, thin provisioning removed, dependency 5427 * on snapshot2 and snapshot removed . . . 5428 * . . . . . . 5429 * ---------------- . . . . . . 5430 * decouple parent: . . . . . . 5431 * ,---------+---------+---------+---------+---------. 5432 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 5433 * +---------+---------+---------+---------+---------+ 5434 * blob | - |zzzzzzzzz| - |yyyyyyyyy| - | 5435 * '---------+---------+---------+---------+---------' 5436 * 5437 * NOTE: needs to allocate 1 cluster, 3 clusters unallocated, dependency 5438 * on snapshot2 removed and on snapshot still exists. Snapshot2 5439 * should remain a clone of snapshot. 5440 */ 5441 static void 5442 _blob_inflate_rw(bool decouple_parent) 5443 { 5444 struct spdk_blob_store *bs; 5445 struct spdk_bs_dev *dev; 5446 struct spdk_blob *blob, *snapshot, *snapshot2; 5447 struct spdk_io_channel *channel; 5448 struct spdk_blob_opts opts; 5449 spdk_blob_id blobid, snapshotid, snapshot2id; 5450 uint64_t free_clusters; 5451 uint64_t cluster_size; 5452 5453 uint64_t payload_size; 5454 uint8_t *payload_read; 5455 uint8_t *payload_write; 5456 uint8_t *payload_clone; 5457 5458 uint64_t pages_per_cluster; 5459 uint64_t pages_per_payload; 5460 5461 int i; 5462 spdk_blob_id ids[2]; 5463 size_t count; 5464 5465 dev = init_dev(); 5466 5467 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5468 poll_threads(); 5469 CU_ASSERT(g_bserrno == 0); 5470 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5471 bs = g_bs; 5472 5473 free_clusters = spdk_bs_free_cluster_count(bs); 5474 cluster_size = spdk_bs_get_cluster_size(bs); 5475 pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs); 5476 pages_per_payload = pages_per_cluster * 5; 5477 5478 payload_size = cluster_size * 5; 5479 5480 payload_read = malloc(payload_size); 5481 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 5482 5483 payload_write = malloc(payload_size); 5484 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 5485 5486 payload_clone = malloc(payload_size); 5487 SPDK_CU_ASSERT_FATAL(payload_clone != NULL); 5488 5489 channel = spdk_bs_alloc_io_channel(bs); 5490 SPDK_CU_ASSERT_FATAL(channel != NULL); 5491 5492 /* Create blob */ 5493 ut_spdk_blob_opts_init(&opts); 5494 opts.thin_provision = true; 5495 opts.num_clusters = 5; 5496 5497 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5498 poll_threads(); 5499 CU_ASSERT(g_bserrno == 0); 5500 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5501 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5502 blobid = g_blobid; 5503 5504 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5505 poll_threads(); 5506 CU_ASSERT(g_bserrno == 0); 5507 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5508 blob = g_blob; 5509 5510 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5511 5512 /* 1) Initial read should return zeroed payload */ 5513 memset(payload_read, 0xFF, payload_size); 5514 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5515 blob_op_complete, NULL); 5516 poll_threads(); 5517 CU_ASSERT(g_bserrno == 0); 5518 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 5519 5520 /* Fill whole blob with a pattern, except last cluster (to be sure it 5521 * isn't allocated) */ 5522 memset(payload_write, 0xE5, payload_size - cluster_size); 5523 spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload - 5524 pages_per_cluster, blob_op_complete, NULL); 5525 poll_threads(); 5526 CU_ASSERT(g_bserrno == 0); 5527 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5528 5529 /* 2) Create snapshot from blob (first level) */ 5530 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5531 poll_threads(); 5532 CU_ASSERT(g_bserrno == 0); 5533 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5534 snapshotid = g_blobid; 5535 5536 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5537 poll_threads(); 5538 CU_ASSERT(g_bserrno == 0); 5539 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5540 snapshot = g_blob; 5541 CU_ASSERT(snapshot->data_ro == true); 5542 CU_ASSERT(snapshot->md_ro == true); 5543 5544 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 5545 5546 /* Write every second cluster with a pattern. 5547 * 5548 * Last cluster shouldn't be written, to be sure that snapshot nor clone 5549 * doesn't allocate it. 5550 * 5551 * payload_clone stores expected result on "blob" read at the time and 5552 * is used only to check data consistency on clone before and after 5553 * inflation. Initially we fill it with a backing snapshots pattern 5554 * used before. 5555 */ 5556 memset(payload_clone, 0xE5, payload_size - cluster_size); 5557 memset(payload_clone + payload_size - cluster_size, 0x00, cluster_size); 5558 memset(payload_write, 0xAA, payload_size); 5559 for (i = 1; i < 5; i += 2) { 5560 spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster, 5561 pages_per_cluster, blob_op_complete, NULL); 5562 poll_threads(); 5563 CU_ASSERT(g_bserrno == 0); 5564 5565 /* Update expected result */ 5566 memcpy(payload_clone + (cluster_size * i), payload_write, 5567 cluster_size); 5568 } 5569 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5570 5571 /* Check data consistency on clone */ 5572 memset(payload_read, 0xFF, payload_size); 5573 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5574 blob_op_complete, NULL); 5575 poll_threads(); 5576 CU_ASSERT(g_bserrno == 0); 5577 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5578 5579 /* 3) Create second levels snapshot from blob */ 5580 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5581 poll_threads(); 5582 CU_ASSERT(g_bserrno == 0); 5583 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5584 snapshot2id = g_blobid; 5585 5586 spdk_bs_open_blob(bs, snapshot2id, blob_op_with_handle_complete, NULL); 5587 poll_threads(); 5588 CU_ASSERT(g_bserrno == 0); 5589 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5590 snapshot2 = g_blob; 5591 CU_ASSERT(snapshot2->data_ro == true); 5592 CU_ASSERT(snapshot2->md_ro == true); 5593 5594 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 5); 5595 5596 CU_ASSERT(snapshot2->parent_id == snapshotid); 5597 5598 /* Write one cluster on the top level blob. This cluster (1) covers 5599 * already allocated cluster in the snapshot2, so shouldn't be inflated 5600 * at all */ 5601 spdk_blob_io_write(blob, channel, payload_write, pages_per_cluster, 5602 pages_per_cluster, blob_op_complete, NULL); 5603 poll_threads(); 5604 CU_ASSERT(g_bserrno == 0); 5605 5606 /* Update expected result */ 5607 memcpy(payload_clone + cluster_size, payload_write, cluster_size); 5608 5609 /* Check data consistency on clone */ 5610 memset(payload_read, 0xFF, payload_size); 5611 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5612 blob_op_complete, NULL); 5613 poll_threads(); 5614 CU_ASSERT(g_bserrno == 0); 5615 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5616 5617 5618 /* Close all blobs */ 5619 spdk_blob_close(blob, blob_op_complete, NULL); 5620 poll_threads(); 5621 CU_ASSERT(g_bserrno == 0); 5622 5623 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5624 poll_threads(); 5625 CU_ASSERT(g_bserrno == 0); 5626 5627 spdk_blob_close(snapshot, blob_op_complete, NULL); 5628 poll_threads(); 5629 CU_ASSERT(g_bserrno == 0); 5630 5631 /* Check snapshot-clone relations */ 5632 count = 2; 5633 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5634 CU_ASSERT(count == 1); 5635 CU_ASSERT(ids[0] == snapshot2id); 5636 5637 count = 2; 5638 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5639 CU_ASSERT(count == 1); 5640 CU_ASSERT(ids[0] == blobid); 5641 5642 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshot2id); 5643 5644 free_clusters = spdk_bs_free_cluster_count(bs); 5645 if (!decouple_parent) { 5646 /* Do full blob inflation */ 5647 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 5648 poll_threads(); 5649 CU_ASSERT(g_bserrno == 0); 5650 5651 /* All clusters should be inflated (except one already allocated 5652 * in a top level blob) */ 5653 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 4); 5654 5655 /* Check if relation tree updated correctly */ 5656 count = 2; 5657 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5658 5659 /* snapshotid have one clone */ 5660 CU_ASSERT(count == 1); 5661 CU_ASSERT(ids[0] == snapshot2id); 5662 5663 /* snapshot2id have no clones */ 5664 count = 2; 5665 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5666 CU_ASSERT(count == 0); 5667 5668 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5669 } else { 5670 /* Decouple parent of blob */ 5671 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 5672 poll_threads(); 5673 CU_ASSERT(g_bserrno == 0); 5674 5675 /* Only one cluster from a parent should be inflated (second one 5676 * is covered by a cluster written on a top level blob, and 5677 * already allocated) */ 5678 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 1); 5679 5680 /* Check if relation tree updated correctly */ 5681 count = 2; 5682 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5683 5684 /* snapshotid have two clones now */ 5685 CU_ASSERT(count == 2); 5686 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5687 CU_ASSERT(ids[0] == snapshot2id || ids[1] == snapshot2id); 5688 5689 /* snapshot2id have no clones */ 5690 count = 2; 5691 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5692 CU_ASSERT(count == 0); 5693 5694 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5695 } 5696 5697 /* Try to delete snapshot2 (should pass) */ 5698 spdk_bs_delete_blob(bs, snapshot2id, blob_op_complete, NULL); 5699 poll_threads(); 5700 CU_ASSERT(g_bserrno == 0); 5701 5702 /* Try to delete base snapshot */ 5703 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5704 poll_threads(); 5705 CU_ASSERT(g_bserrno == 0); 5706 5707 /* Reopen blob after snapshot deletion */ 5708 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5709 poll_threads(); 5710 CU_ASSERT(g_bserrno == 0); 5711 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5712 blob = g_blob; 5713 5714 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5715 5716 /* Check data consistency on inflated blob */ 5717 memset(payload_read, 0xFF, payload_size); 5718 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5719 blob_op_complete, NULL); 5720 poll_threads(); 5721 CU_ASSERT(g_bserrno == 0); 5722 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5723 5724 spdk_blob_close(blob, blob_op_complete, NULL); 5725 poll_threads(); 5726 CU_ASSERT(g_bserrno == 0); 5727 5728 spdk_bs_free_io_channel(channel); 5729 poll_threads(); 5730 5731 /* Unload the blob store */ 5732 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5733 poll_threads(); 5734 CU_ASSERT(g_bserrno == 0); 5735 g_bs = NULL; 5736 g_blob = NULL; 5737 g_blobid = 0; 5738 5739 free(payload_read); 5740 free(payload_write); 5741 free(payload_clone); 5742 } 5743 5744 static void 5745 blob_inflate_rw(void) 5746 { 5747 _blob_inflate_rw(false); 5748 _blob_inflate_rw(true); 5749 } 5750 5751 /** 5752 * Snapshot-clones relation test 5753 * 5754 * snapshot 5755 * | 5756 * +-----+-----+ 5757 * | | 5758 * blob(ro) snapshot2 5759 * | | 5760 * clone2 clone 5761 */ 5762 static void 5763 blob_relations(void) 5764 { 5765 struct spdk_blob_store *bs; 5766 struct spdk_bs_dev *dev; 5767 struct spdk_bs_opts bs_opts; 5768 struct spdk_blob_opts opts; 5769 struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2; 5770 spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2; 5771 int rc; 5772 size_t count; 5773 spdk_blob_id ids[10] = {}; 5774 5775 dev = init_dev(); 5776 spdk_bs_opts_init(&bs_opts); 5777 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5778 5779 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 5780 poll_threads(); 5781 CU_ASSERT(g_bserrno == 0); 5782 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5783 bs = g_bs; 5784 5785 /* 1. Create blob with 10 clusters */ 5786 5787 ut_spdk_blob_opts_init(&opts); 5788 opts.num_clusters = 10; 5789 5790 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5791 poll_threads(); 5792 CU_ASSERT(g_bserrno == 0); 5793 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5794 blobid = g_blobid; 5795 5796 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5797 poll_threads(); 5798 CU_ASSERT(g_bserrno == 0); 5799 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5800 blob = g_blob; 5801 5802 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5803 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5804 CU_ASSERT(!spdk_blob_is_clone(blob)); 5805 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob)); 5806 5807 /* blob should not have underlying snapshot nor clones */ 5808 CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID); 5809 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5810 count = SPDK_COUNTOF(ids); 5811 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5812 CU_ASSERT(rc == 0); 5813 CU_ASSERT(count == 0); 5814 5815 5816 /* 2. Create snapshot */ 5817 5818 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5819 poll_threads(); 5820 CU_ASSERT(g_bserrno == 0); 5821 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5822 snapshotid = g_blobid; 5823 5824 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5825 poll_threads(); 5826 CU_ASSERT(g_bserrno == 0); 5827 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5828 snapshot = g_blob; 5829 5830 CU_ASSERT(spdk_blob_is_read_only(snapshot)); 5831 CU_ASSERT(spdk_blob_is_snapshot(snapshot)); 5832 CU_ASSERT(!spdk_blob_is_clone(snapshot)); 5833 CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID); 5834 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5835 5836 /* Check if original blob is converted to the clone of snapshot */ 5837 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5838 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5839 CU_ASSERT(spdk_blob_is_clone(blob)); 5840 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5841 CU_ASSERT(blob->parent_id == snapshotid); 5842 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5843 5844 count = SPDK_COUNTOF(ids); 5845 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5846 CU_ASSERT(rc == 0); 5847 CU_ASSERT(count == 1); 5848 CU_ASSERT(ids[0] == blobid); 5849 5850 5851 /* 3. Create clone from snapshot */ 5852 5853 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 5854 poll_threads(); 5855 CU_ASSERT(g_bserrno == 0); 5856 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5857 cloneid = g_blobid; 5858 5859 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 5860 poll_threads(); 5861 CU_ASSERT(g_bserrno == 0); 5862 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5863 clone = g_blob; 5864 5865 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5866 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5867 CU_ASSERT(spdk_blob_is_clone(clone)); 5868 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5869 CU_ASSERT(clone->parent_id == snapshotid); 5870 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 5871 5872 count = SPDK_COUNTOF(ids); 5873 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5874 CU_ASSERT(rc == 0); 5875 CU_ASSERT(count == 0); 5876 5877 /* Check if clone is on the snapshot's list */ 5878 count = SPDK_COUNTOF(ids); 5879 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5880 CU_ASSERT(rc == 0); 5881 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5882 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 5883 5884 5885 /* 4. Create snapshot of the clone */ 5886 5887 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 5888 poll_threads(); 5889 CU_ASSERT(g_bserrno == 0); 5890 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5891 snapshotid2 = g_blobid; 5892 5893 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 5894 poll_threads(); 5895 CU_ASSERT(g_bserrno == 0); 5896 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5897 snapshot2 = g_blob; 5898 5899 CU_ASSERT(spdk_blob_is_read_only(snapshot2)); 5900 CU_ASSERT(spdk_blob_is_snapshot(snapshot2)); 5901 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 5902 CU_ASSERT(snapshot2->parent_id == snapshotid); 5903 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5904 5905 /* Check if clone is converted to the clone of snapshot2 and snapshot2 5906 * is a child of snapshot */ 5907 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5908 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5909 CU_ASSERT(spdk_blob_is_clone(clone)); 5910 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5911 CU_ASSERT(clone->parent_id == snapshotid2); 5912 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5913 5914 count = SPDK_COUNTOF(ids); 5915 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5916 CU_ASSERT(rc == 0); 5917 CU_ASSERT(count == 1); 5918 CU_ASSERT(ids[0] == cloneid); 5919 5920 5921 /* 5. Try to create clone from read only blob */ 5922 5923 /* Mark blob as read only */ 5924 spdk_blob_set_read_only(blob); 5925 spdk_blob_sync_md(blob, blob_op_complete, NULL); 5926 poll_threads(); 5927 CU_ASSERT(g_bserrno == 0); 5928 5929 /* Check if previously created blob is read only clone */ 5930 CU_ASSERT(spdk_blob_is_read_only(blob)); 5931 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5932 CU_ASSERT(spdk_blob_is_clone(blob)); 5933 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5934 5935 /* Create clone from read only blob */ 5936 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5937 poll_threads(); 5938 CU_ASSERT(g_bserrno == 0); 5939 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5940 cloneid2 = g_blobid; 5941 5942 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 5943 poll_threads(); 5944 CU_ASSERT(g_bserrno == 0); 5945 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5946 clone2 = g_blob; 5947 5948 CU_ASSERT(!spdk_blob_is_read_only(clone2)); 5949 CU_ASSERT(!spdk_blob_is_snapshot(clone2)); 5950 CU_ASSERT(spdk_blob_is_clone(clone2)); 5951 CU_ASSERT(spdk_blob_is_thin_provisioned(clone2)); 5952 5953 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5954 5955 count = SPDK_COUNTOF(ids); 5956 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5957 CU_ASSERT(rc == 0); 5958 5959 CU_ASSERT(count == 1); 5960 CU_ASSERT(ids[0] == cloneid2); 5961 5962 /* Close blobs */ 5963 5964 spdk_blob_close(clone2, blob_op_complete, NULL); 5965 poll_threads(); 5966 CU_ASSERT(g_bserrno == 0); 5967 5968 spdk_blob_close(blob, blob_op_complete, NULL); 5969 poll_threads(); 5970 CU_ASSERT(g_bserrno == 0); 5971 5972 spdk_blob_close(clone, blob_op_complete, NULL); 5973 poll_threads(); 5974 CU_ASSERT(g_bserrno == 0); 5975 5976 spdk_blob_close(snapshot, blob_op_complete, NULL); 5977 poll_threads(); 5978 CU_ASSERT(g_bserrno == 0); 5979 5980 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5981 poll_threads(); 5982 CU_ASSERT(g_bserrno == 0); 5983 5984 /* Try to delete snapshot with more than 1 clone */ 5985 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5986 poll_threads(); 5987 CU_ASSERT(g_bserrno != 0); 5988 5989 spdk_bs_unload(bs, bs_op_complete, NULL); 5990 poll_threads(); 5991 CU_ASSERT(g_bserrno == 0); 5992 g_bs = NULL; 5993 5994 /* Load an existing blob store */ 5995 dev = init_dev(); 5996 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5997 5998 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 5999 poll_threads(); 6000 CU_ASSERT(g_bserrno == 0); 6001 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6002 bs = g_bs; 6003 6004 6005 /* NULL ids array should return number of clones in count */ 6006 count = SPDK_COUNTOF(ids); 6007 rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count); 6008 CU_ASSERT(rc == -ENOMEM); 6009 CU_ASSERT(count == 2); 6010 6011 /* incorrect array size */ 6012 count = 1; 6013 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 6014 CU_ASSERT(rc == -ENOMEM); 6015 CU_ASSERT(count == 2); 6016 6017 6018 /* Verify structure of loaded blob store */ 6019 6020 /* snapshot */ 6021 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 6022 6023 count = SPDK_COUNTOF(ids); 6024 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 6025 CU_ASSERT(rc == 0); 6026 CU_ASSERT(count == 2); 6027 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 6028 CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2); 6029 6030 /* blob */ 6031 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 6032 count = SPDK_COUNTOF(ids); 6033 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 6034 CU_ASSERT(rc == 0); 6035 CU_ASSERT(count == 1); 6036 CU_ASSERT(ids[0] == cloneid2); 6037 6038 /* clone */ 6039 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 6040 count = SPDK_COUNTOF(ids); 6041 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 6042 CU_ASSERT(rc == 0); 6043 CU_ASSERT(count == 0); 6044 6045 /* snapshot2 */ 6046 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 6047 count = SPDK_COUNTOF(ids); 6048 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6049 CU_ASSERT(rc == 0); 6050 CU_ASSERT(count == 1); 6051 CU_ASSERT(ids[0] == cloneid); 6052 6053 /* clone2 */ 6054 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 6055 count = SPDK_COUNTOF(ids); 6056 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 6057 CU_ASSERT(rc == 0); 6058 CU_ASSERT(count == 0); 6059 6060 /* Try to delete blob that user should not be able to remove */ 6061 6062 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 6063 poll_threads(); 6064 CU_ASSERT(g_bserrno != 0); 6065 6066 /* Remove all blobs */ 6067 6068 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 6069 poll_threads(); 6070 CU_ASSERT(g_bserrno == 0); 6071 6072 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6073 poll_threads(); 6074 CU_ASSERT(g_bserrno == 0); 6075 6076 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 6077 poll_threads(); 6078 CU_ASSERT(g_bserrno == 0); 6079 6080 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 6081 poll_threads(); 6082 CU_ASSERT(g_bserrno == 0); 6083 6084 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 6085 poll_threads(); 6086 CU_ASSERT(g_bserrno == 0); 6087 6088 spdk_bs_unload(bs, bs_op_complete, NULL); 6089 poll_threads(); 6090 CU_ASSERT(g_bserrno == 0); 6091 6092 g_bs = NULL; 6093 } 6094 6095 /** 6096 * Snapshot-clones relation test 2 6097 * 6098 * snapshot1 6099 * | 6100 * snapshot2 6101 * | 6102 * +-----+-----+ 6103 * | | 6104 * blob(ro) snapshot3 6105 * | | 6106 * | snapshot4 6107 * | | | 6108 * clone2 clone clone3 6109 */ 6110 static void 6111 blob_relations2(void) 6112 { 6113 struct spdk_blob_store *bs; 6114 struct spdk_bs_dev *dev; 6115 struct spdk_bs_opts bs_opts; 6116 struct spdk_blob_opts opts; 6117 struct spdk_blob *blob, *snapshot1, *snapshot2, *snapshot3, *snapshot4, *clone, *clone2; 6118 spdk_blob_id blobid, snapshotid1, snapshotid2, snapshotid3, snapshotid4, cloneid, cloneid2, 6119 cloneid3; 6120 int rc; 6121 size_t count; 6122 spdk_blob_id ids[10] = {}; 6123 6124 dev = init_dev(); 6125 spdk_bs_opts_init(&bs_opts); 6126 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 6127 6128 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 6129 poll_threads(); 6130 CU_ASSERT(g_bserrno == 0); 6131 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6132 bs = g_bs; 6133 6134 /* 1. Create blob with 10 clusters */ 6135 6136 ut_spdk_blob_opts_init(&opts); 6137 opts.num_clusters = 10; 6138 6139 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 6140 poll_threads(); 6141 CU_ASSERT(g_bserrno == 0); 6142 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6143 blobid = g_blobid; 6144 6145 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 6146 poll_threads(); 6147 CU_ASSERT(g_bserrno == 0); 6148 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6149 blob = g_blob; 6150 6151 /* 2. Create snapshot1 */ 6152 6153 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6154 poll_threads(); 6155 CU_ASSERT(g_bserrno == 0); 6156 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6157 snapshotid1 = g_blobid; 6158 6159 spdk_bs_open_blob(bs, snapshotid1, blob_op_with_handle_complete, NULL); 6160 poll_threads(); 6161 CU_ASSERT(g_bserrno == 0); 6162 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6163 snapshot1 = g_blob; 6164 6165 CU_ASSERT(snapshot1->parent_id == SPDK_BLOBID_INVALID); 6166 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid1) == SPDK_BLOBID_INVALID); 6167 6168 CU_ASSERT(blob->parent_id == snapshotid1); 6169 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1); 6170 6171 /* Check if blob is the clone of snapshot1 */ 6172 CU_ASSERT(blob->parent_id == snapshotid1); 6173 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1); 6174 6175 count = SPDK_COUNTOF(ids); 6176 rc = spdk_blob_get_clones(bs, snapshotid1, ids, &count); 6177 CU_ASSERT(rc == 0); 6178 CU_ASSERT(count == 1); 6179 CU_ASSERT(ids[0] == blobid); 6180 6181 /* 3. Create another snapshot */ 6182 6183 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6184 poll_threads(); 6185 CU_ASSERT(g_bserrno == 0); 6186 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6187 snapshotid2 = g_blobid; 6188 6189 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 6190 poll_threads(); 6191 CU_ASSERT(g_bserrno == 0); 6192 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6193 snapshot2 = g_blob; 6194 6195 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 6196 CU_ASSERT(snapshot2->parent_id == snapshotid1); 6197 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid1); 6198 6199 /* Check if snapshot2 is the clone of snapshot1 and blob 6200 * is a child of snapshot2 */ 6201 CU_ASSERT(blob->parent_id == snapshotid2); 6202 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2); 6203 6204 count = SPDK_COUNTOF(ids); 6205 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6206 CU_ASSERT(rc == 0); 6207 CU_ASSERT(count == 1); 6208 CU_ASSERT(ids[0] == blobid); 6209 6210 /* 4. Create clone from snapshot */ 6211 6212 spdk_bs_create_clone(bs, snapshotid2, NULL, blob_op_with_id_complete, NULL); 6213 poll_threads(); 6214 CU_ASSERT(g_bserrno == 0); 6215 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6216 cloneid = g_blobid; 6217 6218 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 6219 poll_threads(); 6220 CU_ASSERT(g_bserrno == 0); 6221 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6222 clone = g_blob; 6223 6224 CU_ASSERT(clone->parent_id == snapshotid2); 6225 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 6226 6227 /* Check if clone is on the snapshot's list */ 6228 count = SPDK_COUNTOF(ids); 6229 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6230 CU_ASSERT(rc == 0); 6231 CU_ASSERT(count == 2); 6232 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 6233 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 6234 6235 /* 5. Create snapshot of the clone */ 6236 6237 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 6238 poll_threads(); 6239 CU_ASSERT(g_bserrno == 0); 6240 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6241 snapshotid3 = g_blobid; 6242 6243 spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL); 6244 poll_threads(); 6245 CU_ASSERT(g_bserrno == 0); 6246 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6247 snapshot3 = g_blob; 6248 6249 CU_ASSERT(snapshot3->parent_id == snapshotid2); 6250 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2); 6251 6252 /* Check if clone is converted to the clone of snapshot3 and snapshot3 6253 * is a child of snapshot2 */ 6254 CU_ASSERT(clone->parent_id == snapshotid3); 6255 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 6256 6257 count = SPDK_COUNTOF(ids); 6258 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 6259 CU_ASSERT(rc == 0); 6260 CU_ASSERT(count == 1); 6261 CU_ASSERT(ids[0] == cloneid); 6262 6263 /* 6. Create another snapshot of the clone */ 6264 6265 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 6266 poll_threads(); 6267 CU_ASSERT(g_bserrno == 0); 6268 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6269 snapshotid4 = g_blobid; 6270 6271 spdk_bs_open_blob(bs, snapshotid4, blob_op_with_handle_complete, NULL); 6272 poll_threads(); 6273 CU_ASSERT(g_bserrno == 0); 6274 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6275 snapshot4 = g_blob; 6276 6277 CU_ASSERT(snapshot4->parent_id == snapshotid3); 6278 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid4) == snapshotid3); 6279 6280 /* Check if clone is converted to the clone of snapshot4 and snapshot4 6281 * is a child of snapshot3 */ 6282 CU_ASSERT(clone->parent_id == snapshotid4); 6283 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid4); 6284 6285 count = SPDK_COUNTOF(ids); 6286 rc = spdk_blob_get_clones(bs, snapshotid4, ids, &count); 6287 CU_ASSERT(rc == 0); 6288 CU_ASSERT(count == 1); 6289 CU_ASSERT(ids[0] == cloneid); 6290 6291 /* 7. Remove snapshot 4 */ 6292 6293 spdk_blob_close(snapshot4, blob_op_complete, NULL); 6294 poll_threads(); 6295 CU_ASSERT(g_bserrno == 0); 6296 6297 spdk_bs_delete_blob(bs, snapshotid4, blob_op_complete, NULL); 6298 poll_threads(); 6299 CU_ASSERT(g_bserrno == 0); 6300 6301 /* Check if relations are back to state from before creating snapshot 4 */ 6302 CU_ASSERT(clone->parent_id == snapshotid3); 6303 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 6304 6305 count = SPDK_COUNTOF(ids); 6306 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 6307 CU_ASSERT(rc == 0); 6308 CU_ASSERT(count == 1); 6309 CU_ASSERT(ids[0] == cloneid); 6310 6311 /* 8. Create second clone of snapshot 3 and try to remove snapshot 3 */ 6312 6313 spdk_bs_create_clone(bs, snapshotid3, NULL, blob_op_with_id_complete, NULL); 6314 poll_threads(); 6315 CU_ASSERT(g_bserrno == 0); 6316 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6317 cloneid3 = g_blobid; 6318 6319 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 6320 poll_threads(); 6321 CU_ASSERT(g_bserrno != 0); 6322 6323 /* 9. Open snapshot 3 again and try to remove it while clone 3 is closed */ 6324 6325 spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL); 6326 poll_threads(); 6327 CU_ASSERT(g_bserrno == 0); 6328 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6329 snapshot3 = g_blob; 6330 6331 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 6332 poll_threads(); 6333 CU_ASSERT(g_bserrno != 0); 6334 6335 spdk_blob_close(snapshot3, blob_op_complete, NULL); 6336 poll_threads(); 6337 CU_ASSERT(g_bserrno == 0); 6338 6339 spdk_bs_delete_blob(bs, cloneid3, blob_op_complete, NULL); 6340 poll_threads(); 6341 CU_ASSERT(g_bserrno == 0); 6342 6343 /* 10. Remove snapshot 1 */ 6344 6345 spdk_blob_close(snapshot1, blob_op_complete, NULL); 6346 poll_threads(); 6347 CU_ASSERT(g_bserrno == 0); 6348 6349 spdk_bs_delete_blob(bs, snapshotid1, blob_op_complete, NULL); 6350 poll_threads(); 6351 CU_ASSERT(g_bserrno == 0); 6352 6353 /* Check if relations are back to state from before creating snapshot 4 (before step 6) */ 6354 CU_ASSERT(snapshot2->parent_id == SPDK_BLOBID_INVALID); 6355 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID); 6356 6357 count = SPDK_COUNTOF(ids); 6358 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6359 CU_ASSERT(rc == 0); 6360 CU_ASSERT(count == 2); 6361 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 6362 CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3); 6363 6364 /* 11. Try to create clone from read only blob */ 6365 6366 /* Mark blob as read only */ 6367 spdk_blob_set_read_only(blob); 6368 spdk_blob_sync_md(blob, blob_op_complete, NULL); 6369 poll_threads(); 6370 CU_ASSERT(g_bserrno == 0); 6371 6372 /* Create clone from read only blob */ 6373 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6374 poll_threads(); 6375 CU_ASSERT(g_bserrno == 0); 6376 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6377 cloneid2 = g_blobid; 6378 6379 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 6380 poll_threads(); 6381 CU_ASSERT(g_bserrno == 0); 6382 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6383 clone2 = g_blob; 6384 6385 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 6386 6387 count = SPDK_COUNTOF(ids); 6388 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 6389 CU_ASSERT(rc == 0); 6390 CU_ASSERT(count == 1); 6391 CU_ASSERT(ids[0] == cloneid2); 6392 6393 /* Close blobs */ 6394 6395 spdk_blob_close(clone2, blob_op_complete, NULL); 6396 poll_threads(); 6397 CU_ASSERT(g_bserrno == 0); 6398 6399 spdk_blob_close(blob, blob_op_complete, NULL); 6400 poll_threads(); 6401 CU_ASSERT(g_bserrno == 0); 6402 6403 spdk_blob_close(clone, blob_op_complete, NULL); 6404 poll_threads(); 6405 CU_ASSERT(g_bserrno == 0); 6406 6407 spdk_blob_close(snapshot2, blob_op_complete, NULL); 6408 poll_threads(); 6409 CU_ASSERT(g_bserrno == 0); 6410 6411 spdk_blob_close(snapshot3, blob_op_complete, NULL); 6412 poll_threads(); 6413 CU_ASSERT(g_bserrno == 0); 6414 6415 spdk_bs_unload(bs, bs_op_complete, NULL); 6416 poll_threads(); 6417 CU_ASSERT(g_bserrno == 0); 6418 g_bs = NULL; 6419 6420 /* Load an existing blob store */ 6421 dev = init_dev(); 6422 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 6423 6424 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 6425 poll_threads(); 6426 CU_ASSERT(g_bserrno == 0); 6427 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6428 bs = g_bs; 6429 6430 /* Verify structure of loaded blob store */ 6431 6432 /* snapshot2 */ 6433 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID); 6434 6435 count = SPDK_COUNTOF(ids); 6436 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6437 CU_ASSERT(rc == 0); 6438 CU_ASSERT(count == 2); 6439 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 6440 CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3); 6441 6442 /* blob */ 6443 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2); 6444 count = SPDK_COUNTOF(ids); 6445 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 6446 CU_ASSERT(rc == 0); 6447 CU_ASSERT(count == 1); 6448 CU_ASSERT(ids[0] == cloneid2); 6449 6450 /* clone */ 6451 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 6452 count = SPDK_COUNTOF(ids); 6453 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 6454 CU_ASSERT(rc == 0); 6455 CU_ASSERT(count == 0); 6456 6457 /* snapshot3 */ 6458 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2); 6459 count = SPDK_COUNTOF(ids); 6460 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 6461 CU_ASSERT(rc == 0); 6462 CU_ASSERT(count == 1); 6463 CU_ASSERT(ids[0] == cloneid); 6464 6465 /* clone2 */ 6466 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 6467 count = SPDK_COUNTOF(ids); 6468 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 6469 CU_ASSERT(rc == 0); 6470 CU_ASSERT(count == 0); 6471 6472 /* Try to delete all blobs in the worse possible order */ 6473 6474 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6475 poll_threads(); 6476 CU_ASSERT(g_bserrno != 0); 6477 6478 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 6479 poll_threads(); 6480 CU_ASSERT(g_bserrno == 0); 6481 6482 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6483 poll_threads(); 6484 CU_ASSERT(g_bserrno != 0); 6485 6486 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 6487 poll_threads(); 6488 CU_ASSERT(g_bserrno == 0); 6489 6490 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6491 poll_threads(); 6492 CU_ASSERT(g_bserrno == 0); 6493 6494 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 6495 poll_threads(); 6496 CU_ASSERT(g_bserrno == 0); 6497 6498 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 6499 poll_threads(); 6500 CU_ASSERT(g_bserrno == 0); 6501 6502 spdk_bs_unload(bs, bs_op_complete, NULL); 6503 poll_threads(); 6504 CU_ASSERT(g_bserrno == 0); 6505 6506 g_bs = NULL; 6507 } 6508 6509 static void 6510 blob_delete_snapshot_power_failure(void) 6511 { 6512 struct spdk_blob_store *bs; 6513 struct spdk_bs_dev *dev; 6514 struct spdk_blob_opts opts; 6515 struct spdk_blob *blob, *snapshot; 6516 struct spdk_power_failure_thresholds thresholds = {}; 6517 spdk_blob_id blobid, snapshotid; 6518 const void *value; 6519 size_t value_len; 6520 size_t count; 6521 spdk_blob_id ids[3] = {}; 6522 int rc; 6523 bool deleted = false; 6524 6525 dev = init_dev(); 6526 6527 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 6528 poll_threads(); 6529 CU_ASSERT(g_bserrno == 0); 6530 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6531 bs = g_bs; 6532 6533 /* Create blob */ 6534 ut_spdk_blob_opts_init(&opts); 6535 opts.num_clusters = 10; 6536 6537 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 6538 poll_threads(); 6539 CU_ASSERT(g_bserrno == 0); 6540 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6541 blobid = g_blobid; 6542 6543 /* Create snapshot */ 6544 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6545 poll_threads(); 6546 CU_ASSERT(g_bserrno == 0); 6547 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6548 snapshotid = g_blobid; 6549 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6550 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6551 6552 thresholds.general_threshold = 1; 6553 while (!deleted) { 6554 dev_set_power_failure_thresholds(thresholds); 6555 6556 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 6557 poll_threads(); 6558 6559 /* Do not shut down cleanly. Assumption is that after snapshot deletion 6560 * reports success, changes to both blobs should already persisted. */ 6561 _spdk_bs_free(bs); 6562 6563 dev_reset_power_failure_event(); 6564 6565 dev = init_dev(); 6566 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 6567 poll_threads(); 6568 CU_ASSERT(g_bserrno == 0); 6569 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6570 bs = g_bs; 6571 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6572 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6573 6574 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 6575 poll_threads(); 6576 CU_ASSERT(g_bserrno == 0); 6577 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6578 blob = g_blob; 6579 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true); 6580 6581 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 6582 poll_threads(); 6583 6584 if (g_bserrno == 0) { 6585 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6586 snapshot = g_blob; 6587 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 6588 count = SPDK_COUNTOF(ids); 6589 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 6590 CU_ASSERT(rc == 0); 6591 CU_ASSERT(count == 1); 6592 CU_ASSERT(ids[0] == blobid); 6593 rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_PENDING_REMOVAL, &value, &value_len); 6594 CU_ASSERT(rc != 0); 6595 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(snapshot) == false); 6596 6597 spdk_blob_close(snapshot, blob_op_complete, NULL); 6598 poll_threads(); 6599 CU_ASSERT(g_bserrno == 0); 6600 } else { 6601 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 6602 deleted = true; 6603 } 6604 6605 spdk_blob_close(blob, blob_op_complete, NULL); 6606 poll_threads(); 6607 CU_ASSERT(g_bserrno == 0); 6608 6609 /* Reload blobstore to have the same starting conditions (as the previous blobstore load 6610 * may trigger cleanup after power failure or may not) */ 6611 spdk_bs_unload(g_bs, bs_op_complete, NULL); 6612 poll_threads(); 6613 CU_ASSERT(g_bserrno == 0); 6614 6615 dev = init_dev(); 6616 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 6617 poll_threads(); 6618 CU_ASSERT(g_bserrno == 0); 6619 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6620 bs = g_bs; 6621 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6622 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6623 6624 thresholds.general_threshold++; 6625 } 6626 6627 spdk_bs_unload(g_bs, bs_op_complete, NULL); 6628 poll_threads(); 6629 CU_ASSERT(g_bserrno == 0); 6630 g_bs = NULL; 6631 } 6632 6633 static void 6634 blob_create_snapshot_power_failure(void) 6635 { 6636 struct spdk_blob_store *bs; 6637 struct spdk_bs_dev *dev; 6638 struct spdk_blob_opts opts; 6639 struct spdk_blob *blob, *snapshot; 6640 struct spdk_power_failure_thresholds thresholds = {}; 6641 spdk_blob_id blobid, snapshotid; 6642 const void *value; 6643 size_t value_len; 6644 size_t count; 6645 spdk_blob_id ids[3] = {}; 6646 int rc; 6647 bool created = false; 6648 6649 dev = init_dev(); 6650 6651 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 6652 poll_threads(); 6653 CU_ASSERT(g_bserrno == 0); 6654 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6655 bs = g_bs; 6656 6657 /* Create blob */ 6658 ut_spdk_blob_opts_init(&opts); 6659 opts.num_clusters = 10; 6660 6661 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 6662 poll_threads(); 6663 CU_ASSERT(g_bserrno == 0); 6664 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6665 blobid = g_blobid; 6666 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6667 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6668 6669 thresholds.general_threshold = 1; 6670 while (!created) { 6671 dev_set_power_failure_thresholds(thresholds); 6672 6673 /* Create snapshot */ 6674 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6675 poll_threads(); 6676 snapshotid = g_blobid; 6677 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6678 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6679 6680 /* Do not shut down cleanly. Assumption is that after create snapshot 6681 * reports success, both blobs should be power-fail safe. */ 6682 _spdk_bs_free(bs); 6683 6684 dev_reset_power_failure_event(); 6685 6686 dev = init_dev(); 6687 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 6688 poll_threads(); 6689 CU_ASSERT(g_bserrno == 0); 6690 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6691 bs = g_bs; 6692 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6693 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6694 6695 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 6696 poll_threads(); 6697 CU_ASSERT(g_bserrno == 0); 6698 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6699 blob = g_blob; 6700 6701 if (snapshotid != SPDK_BLOBID_INVALID) { 6702 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 6703 poll_threads(); 6704 } 6705 6706 if ((snapshotid != SPDK_BLOBID_INVALID) && (g_bserrno == 0)) { 6707 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6708 snapshot = g_blob; 6709 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true); 6710 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(snapshot) == false); 6711 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 6712 count = SPDK_COUNTOF(ids); 6713 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 6714 CU_ASSERT(rc == 0); 6715 CU_ASSERT(count == 1); 6716 CU_ASSERT(ids[0] == blobid); 6717 rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_IN_PROGRESS, &value, &value_len); 6718 CU_ASSERT(rc != 0); 6719 6720 spdk_blob_close(snapshot, blob_op_complete, NULL); 6721 poll_threads(); 6722 CU_ASSERT(g_bserrno == 0); 6723 created = true; 6724 } else { 6725 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 6726 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == false); 6727 } 6728 6729 spdk_blob_close(blob, blob_op_complete, NULL); 6730 poll_threads(); 6731 CU_ASSERT(g_bserrno == 0); 6732 6733 /* Reload blobstore to have the same starting conditions (as the previous blobstore load 6734 * may trigger cleanup after power failure or may not) */ 6735 spdk_bs_unload(g_bs, bs_op_complete, NULL); 6736 poll_threads(); 6737 CU_ASSERT(g_bserrno == 0); 6738 6739 dev = init_dev(); 6740 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 6741 poll_threads(); 6742 CU_ASSERT(g_bserrno == 0); 6743 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6744 bs = g_bs; 6745 SPDK_CU_ASSERT_FATAL(spdk_bit_array_get(bs->used_clusters, 1)); 6746 SPDK_CU_ASSERT_FATAL(!spdk_bit_array_get(bs->used_clusters, 11)); 6747 6748 thresholds.general_threshold++; 6749 } 6750 6751 spdk_bs_unload(g_bs, bs_op_complete, NULL); 6752 poll_threads(); 6753 CU_ASSERT(g_bserrno == 0); 6754 g_bs = NULL; 6755 } 6756 6757 static void 6758 test_io_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6759 { 6760 uint8_t payload_ff[64 * 512]; 6761 uint8_t payload_aa[64 * 512]; 6762 uint8_t payload_00[64 * 512]; 6763 uint8_t *cluster0, *cluster1; 6764 6765 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6766 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6767 memset(payload_00, 0x00, sizeof(payload_00)); 6768 6769 /* Try to perform I/O with io unit = 512 */ 6770 spdk_blob_io_write(blob, channel, payload_ff, 0, 1, blob_op_complete, NULL); 6771 poll_threads(); 6772 CU_ASSERT(g_bserrno == 0); 6773 6774 /* If thin provisioned is set cluster should be allocated now */ 6775 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 6776 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6777 6778 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 6779 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 6780 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6781 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6782 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 6783 6784 /* Verify write with offset on first page */ 6785 spdk_blob_io_write(blob, channel, payload_ff, 2, 1, blob_op_complete, NULL); 6786 poll_threads(); 6787 CU_ASSERT(g_bserrno == 0); 6788 6789 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6790 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6791 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6792 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6793 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6794 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 6795 6796 /* Verify write with offset on first page */ 6797 spdk_blob_io_write(blob, channel, payload_ff, 4, 4, blob_op_complete, NULL); 6798 poll_threads(); 6799 6800 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6801 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6802 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6803 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6804 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6805 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 6806 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 6807 6808 /* Verify write with offset on second page */ 6809 spdk_blob_io_write(blob, channel, payload_ff, 8, 4, blob_op_complete, NULL); 6810 poll_threads(); 6811 6812 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 6813 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6814 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6815 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6816 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6817 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 6818 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6819 6820 /* Verify write across multiple pages */ 6821 spdk_blob_io_write(blob, channel, payload_aa, 4, 8, blob_op_complete, NULL); 6822 poll_threads(); 6823 6824 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 6825 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6826 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6827 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6828 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6829 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6830 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6831 6832 /* Verify write across multiple clusters */ 6833 spdk_blob_io_write(blob, channel, payload_ff, 28, 8, blob_op_complete, NULL); 6834 poll_threads(); 6835 6836 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6837 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6838 6839 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6840 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6841 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6842 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6843 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6844 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6845 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6846 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6847 6848 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6849 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 6850 6851 /* Verify write to second cluster */ 6852 spdk_blob_io_write(blob, channel, payload_ff, 32 + 12, 2, blob_op_complete, NULL); 6853 poll_threads(); 6854 6855 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6856 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6857 6858 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6859 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 6860 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6861 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6862 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6863 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6864 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6865 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6866 6867 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6868 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 6869 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 6870 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 6871 } 6872 6873 static void 6874 test_io_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6875 { 6876 uint8_t payload_read[64 * 512]; 6877 uint8_t payload_ff[64 * 512]; 6878 uint8_t payload_aa[64 * 512]; 6879 uint8_t payload_00[64 * 512]; 6880 6881 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6882 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6883 memset(payload_00, 0x00, sizeof(payload_00)); 6884 6885 /* Read only first io unit */ 6886 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6887 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6888 * payload_read: F000 0000 | 0000 0000 ... */ 6889 memset(payload_read, 0x00, sizeof(payload_read)); 6890 spdk_blob_io_read(blob, channel, payload_read, 0, 1, blob_op_complete, NULL); 6891 poll_threads(); 6892 CU_ASSERT(g_bserrno == 0); 6893 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6894 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 6895 6896 /* Read four io_units starting from offset = 2 6897 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6898 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6899 * payload_read: F0AA 0000 | 0000 0000 ... */ 6900 6901 memset(payload_read, 0x00, sizeof(payload_read)); 6902 spdk_blob_io_read(blob, channel, payload_read, 2, 4, blob_op_complete, NULL); 6903 poll_threads(); 6904 CU_ASSERT(g_bserrno == 0); 6905 6906 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6907 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6908 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 6909 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 6910 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6911 6912 /* Read eight io_units across multiple pages 6913 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6914 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6915 * payload_read: AAAA AAAA | 0000 0000 ... */ 6916 memset(payload_read, 0x00, sizeof(payload_read)); 6917 spdk_blob_io_read(blob, channel, payload_read, 4, 8, blob_op_complete, NULL); 6918 poll_threads(); 6919 CU_ASSERT(g_bserrno == 0); 6920 6921 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 6922 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6923 6924 /* Read eight io_units across multiple clusters 6925 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 6926 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6927 * payload_read: FFFF FFFF | 0000 0000 ... */ 6928 memset(payload_read, 0x00, sizeof(payload_read)); 6929 spdk_blob_io_read(blob, channel, payload_read, 28, 8, blob_op_complete, NULL); 6930 poll_threads(); 6931 CU_ASSERT(g_bserrno == 0); 6932 6933 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 6934 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6935 6936 /* Read four io_units from second cluster 6937 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6938 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 6939 * payload_read: 00FF 0000 | 0000 0000 ... */ 6940 memset(payload_read, 0x00, sizeof(payload_read)); 6941 spdk_blob_io_read(blob, channel, payload_read, 32 + 10, 4, blob_op_complete, NULL); 6942 poll_threads(); 6943 CU_ASSERT(g_bserrno == 0); 6944 6945 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 6946 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 6947 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6948 6949 /* Read second cluster 6950 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6951 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 6952 * payload_read: FFFF 0000 | 0000 FF00 ... */ 6953 memset(payload_read, 0x00, sizeof(payload_read)); 6954 spdk_blob_io_read(blob, channel, payload_read, 32, 32, blob_op_complete, NULL); 6955 poll_threads(); 6956 CU_ASSERT(g_bserrno == 0); 6957 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 6958 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 6959 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 6960 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 6961 6962 /* Read whole two clusters 6963 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6964 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 6965 memset(payload_read, 0x00, sizeof(payload_read)); 6966 spdk_blob_io_read(blob, channel, payload_read, 0, 64, blob_op_complete, NULL); 6967 poll_threads(); 6968 CU_ASSERT(g_bserrno == 0); 6969 6970 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6971 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6972 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 6973 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 6974 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 6975 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 6976 6977 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 6978 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 6979 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 6980 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 6981 } 6982 6983 6984 static void 6985 test_io_unmap(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6986 { 6987 uint8_t payload_ff[64 * 512]; 6988 uint8_t payload_aa[64 * 512]; 6989 uint8_t payload_00[64 * 512]; 6990 uint8_t *cluster0, *cluster1; 6991 6992 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6993 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6994 memset(payload_00, 0x00, sizeof(payload_00)); 6995 6996 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6997 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6998 6999 /* Unmap */ 7000 spdk_blob_io_unmap(blob, channel, 0, 64, blob_op_complete, NULL); 7001 poll_threads(); 7002 7003 CU_ASSERT(g_bserrno == 0); 7004 7005 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 7006 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 7007 } 7008 7009 static void 7010 test_io_zeroes(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 7011 { 7012 uint8_t payload_ff[64 * 512]; 7013 uint8_t payload_aa[64 * 512]; 7014 uint8_t payload_00[64 * 512]; 7015 uint8_t *cluster0, *cluster1; 7016 7017 memset(payload_ff, 0xFF, sizeof(payload_ff)); 7018 memset(payload_aa, 0xAA, sizeof(payload_aa)); 7019 memset(payload_00, 0x00, sizeof(payload_00)); 7020 7021 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 7022 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 7023 7024 /* Write zeroes */ 7025 spdk_blob_io_write_zeroes(blob, channel, 0, 64, blob_op_complete, NULL); 7026 poll_threads(); 7027 7028 CU_ASSERT(g_bserrno == 0); 7029 7030 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 7031 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 7032 } 7033 7034 7035 static void 7036 test_iov_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 7037 { 7038 uint8_t payload_ff[64 * 512]; 7039 uint8_t payload_aa[64 * 512]; 7040 uint8_t payload_00[64 * 512]; 7041 uint8_t *cluster0, *cluster1; 7042 struct iovec iov[4]; 7043 7044 memset(payload_ff, 0xFF, sizeof(payload_ff)); 7045 memset(payload_aa, 0xAA, sizeof(payload_aa)); 7046 memset(payload_00, 0x00, sizeof(payload_00)); 7047 7048 /* Try to perform I/O with io unit = 512 */ 7049 iov[0].iov_base = payload_ff; 7050 iov[0].iov_len = 1 * 512; 7051 spdk_blob_io_writev(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 7052 poll_threads(); 7053 CU_ASSERT(g_bserrno == 0); 7054 7055 /* If thin provisioned is set cluster should be allocated now */ 7056 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 7057 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 7058 7059 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 7060 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 7061 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 7062 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7063 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 7064 7065 /* Verify write with offset on first page */ 7066 iov[0].iov_base = payload_ff; 7067 iov[0].iov_len = 1 * 512; 7068 spdk_blob_io_writev(blob, channel, iov, 1, 2, 1, blob_op_complete, NULL); 7069 poll_threads(); 7070 CU_ASSERT(g_bserrno == 0); 7071 7072 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 7073 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7074 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 7075 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 7076 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 7077 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 7078 7079 /* Verify write with offset on first page */ 7080 iov[0].iov_base = payload_ff; 7081 iov[0].iov_len = 4 * 512; 7082 spdk_blob_io_writev(blob, channel, iov, 1, 4, 4, blob_op_complete, NULL); 7083 poll_threads(); 7084 7085 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 7086 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7087 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 7088 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 7089 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 7090 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 7091 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 7092 7093 /* Verify write with offset on second page */ 7094 iov[0].iov_base = payload_ff; 7095 iov[0].iov_len = 4 * 512; 7096 spdk_blob_io_writev(blob, channel, iov, 1, 8, 4, blob_op_complete, NULL); 7097 poll_threads(); 7098 7099 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 7100 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7101 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 7102 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 7103 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 7104 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 7105 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 7106 7107 /* Verify write across multiple pages */ 7108 iov[0].iov_base = payload_aa; 7109 iov[0].iov_len = 8 * 512; 7110 spdk_blob_io_writev(blob, channel, iov, 1, 4, 8, blob_op_complete, NULL); 7111 poll_threads(); 7112 7113 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 7114 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7115 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 7116 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 7117 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 7118 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 7119 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 7120 7121 /* Verify write across multiple clusters */ 7122 7123 iov[0].iov_base = payload_ff; 7124 iov[0].iov_len = 8 * 512; 7125 spdk_blob_io_writev(blob, channel, iov, 1, 28, 8, blob_op_complete, NULL); 7126 poll_threads(); 7127 7128 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 7129 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 7130 7131 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7132 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 7133 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7134 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 7135 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 7136 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 7137 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 7138 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 16 * 512) == 0); 7139 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 7140 7141 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 7142 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 7143 7144 /* Verify write to second cluster */ 7145 7146 iov[0].iov_base = payload_ff; 7147 iov[0].iov_len = 2 * 512; 7148 spdk_blob_io_writev(blob, channel, iov, 1, 32 + 12, 2, blob_op_complete, NULL); 7149 poll_threads(); 7150 7151 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 7152 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 7153 7154 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7155 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 7156 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 7157 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 7158 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 7159 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 7160 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 7161 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 7162 7163 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 7164 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 7165 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 7166 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 7167 } 7168 7169 static void 7170 test_iov_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 7171 { 7172 uint8_t payload_read[64 * 512]; 7173 uint8_t payload_ff[64 * 512]; 7174 uint8_t payload_aa[64 * 512]; 7175 uint8_t payload_00[64 * 512]; 7176 struct iovec iov[4]; 7177 7178 memset(payload_ff, 0xFF, sizeof(payload_ff)); 7179 memset(payload_aa, 0xAA, sizeof(payload_aa)); 7180 memset(payload_00, 0x00, sizeof(payload_00)); 7181 7182 /* Read only first io unit */ 7183 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7184 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 7185 * payload_read: F000 0000 | 0000 0000 ... */ 7186 memset(payload_read, 0x00, sizeof(payload_read)); 7187 iov[0].iov_base = payload_read; 7188 iov[0].iov_len = 1 * 512; 7189 spdk_blob_io_readv(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 7190 poll_threads(); 7191 7192 CU_ASSERT(g_bserrno == 0); 7193 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 7194 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 7195 7196 /* Read four io_units starting from offset = 2 7197 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7198 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 7199 * payload_read: F0AA 0000 | 0000 0000 ... */ 7200 7201 memset(payload_read, 0x00, sizeof(payload_read)); 7202 iov[0].iov_base = payload_read; 7203 iov[0].iov_len = 4 * 512; 7204 spdk_blob_io_readv(blob, channel, iov, 1, 2, 4, blob_op_complete, NULL); 7205 poll_threads(); 7206 CU_ASSERT(g_bserrno == 0); 7207 7208 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 7209 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 7210 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 7211 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 7212 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 7213 7214 /* Read eight io_units across multiple pages 7215 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 7216 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 7217 * payload_read: AAAA AAAA | 0000 0000 ... */ 7218 memset(payload_read, 0x00, sizeof(payload_read)); 7219 iov[0].iov_base = payload_read; 7220 iov[0].iov_len = 4 * 512; 7221 iov[1].iov_base = payload_read + 4 * 512; 7222 iov[1].iov_len = 4 * 512; 7223 spdk_blob_io_readv(blob, channel, iov, 2, 4, 8, blob_op_complete, NULL); 7224 poll_threads(); 7225 CU_ASSERT(g_bserrno == 0); 7226 7227 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 7228 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 7229 7230 /* Read eight io_units across multiple clusters 7231 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 7232 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 7233 * payload_read: FFFF FFFF | 0000 0000 ... */ 7234 memset(payload_read, 0x00, sizeof(payload_read)); 7235 iov[0].iov_base = payload_read; 7236 iov[0].iov_len = 2 * 512; 7237 iov[1].iov_base = payload_read + 2 * 512; 7238 iov[1].iov_len = 2 * 512; 7239 iov[2].iov_base = payload_read + 4 * 512; 7240 iov[2].iov_len = 2 * 512; 7241 iov[3].iov_base = payload_read + 6 * 512; 7242 iov[3].iov_len = 2 * 512; 7243 spdk_blob_io_readv(blob, channel, iov, 4, 28, 8, blob_op_complete, NULL); 7244 poll_threads(); 7245 CU_ASSERT(g_bserrno == 0); 7246 7247 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 7248 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 7249 7250 /* Read four io_units from second cluster 7251 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7252 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 7253 * payload_read: 00FF 0000 | 0000 0000 ... */ 7254 memset(payload_read, 0x00, sizeof(payload_read)); 7255 iov[0].iov_base = payload_read; 7256 iov[0].iov_len = 1 * 512; 7257 iov[1].iov_base = payload_read + 1 * 512; 7258 iov[1].iov_len = 3 * 512; 7259 spdk_blob_io_readv(blob, channel, iov, 2, 32 + 10, 4, blob_op_complete, NULL); 7260 poll_threads(); 7261 CU_ASSERT(g_bserrno == 0); 7262 7263 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 7264 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 7265 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 7266 7267 /* Read second cluster 7268 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 7269 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 7270 * payload_read: FFFF 0000 | 0000 FF00 ... */ 7271 memset(payload_read, 0x00, sizeof(payload_read)); 7272 iov[0].iov_base = payload_read; 7273 iov[0].iov_len = 1 * 512; 7274 iov[1].iov_base = payload_read + 1 * 512; 7275 iov[1].iov_len = 2 * 512; 7276 iov[2].iov_base = payload_read + 3 * 512; 7277 iov[2].iov_len = 4 * 512; 7278 iov[3].iov_base = payload_read + 7 * 512; 7279 iov[3].iov_len = 25 * 512; 7280 spdk_blob_io_readv(blob, channel, iov, 4, 32, 32, blob_op_complete, NULL); 7281 poll_threads(); 7282 CU_ASSERT(g_bserrno == 0); 7283 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 7284 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 7285 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 7286 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 7287 7288 /* Read whole two clusters 7289 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 7290 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 7291 memset(payload_read, 0x00, sizeof(payload_read)); 7292 iov[0].iov_base = payload_read; 7293 iov[0].iov_len = 1 * 512; 7294 iov[1].iov_base = payload_read + 1 * 512; 7295 iov[1].iov_len = 8 * 512; 7296 iov[2].iov_base = payload_read + 9 * 512; 7297 iov[2].iov_len = 16 * 512; 7298 iov[3].iov_base = payload_read + 25 * 512; 7299 iov[3].iov_len = 39 * 512; 7300 spdk_blob_io_readv(blob, channel, iov, 4, 0, 64, blob_op_complete, NULL); 7301 poll_threads(); 7302 CU_ASSERT(g_bserrno == 0); 7303 7304 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 7305 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 7306 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 7307 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 7308 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 7309 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 7310 7311 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 7312 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 7313 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 7314 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 7315 } 7316 7317 static void 7318 blob_io_unit(void) 7319 { 7320 struct spdk_bs_opts bsopts; 7321 struct spdk_blob_opts opts; 7322 struct spdk_bs_dev *dev; 7323 struct spdk_blob *blob, *snapshot, *clone; 7324 spdk_blob_id blobid; 7325 struct spdk_io_channel *channel; 7326 7327 /* Create dev with 512 bytes io unit size */ 7328 7329 spdk_bs_opts_init(&bsopts); 7330 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 7331 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 7332 7333 /* Try to initialize a new blob store with unsupported io_unit */ 7334 dev = init_dev(); 7335 dev->blocklen = 512; 7336 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 7337 7338 /* Initialize a new blob store */ 7339 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 7340 poll_threads(); 7341 CU_ASSERT(g_bserrno == 0); 7342 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7343 7344 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512); 7345 channel = spdk_bs_alloc_io_channel(g_bs); 7346 7347 /* Create thick provisioned blob */ 7348 ut_spdk_blob_opts_init(&opts); 7349 opts.thin_provision = false; 7350 opts.num_clusters = 32; 7351 7352 spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL); 7353 poll_threads(); 7354 7355 CU_ASSERT(g_bserrno == 0); 7356 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7357 blobid = g_blobid; 7358 7359 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 7360 poll_threads(); 7361 CU_ASSERT(g_bserrno == 0); 7362 CU_ASSERT(g_blob != NULL); 7363 blob = g_blob; 7364 7365 test_io_write(dev, blob, channel); 7366 test_io_read(dev, blob, channel); 7367 test_io_zeroes(dev, blob, channel); 7368 7369 test_iov_write(dev, blob, channel); 7370 test_iov_read(dev, blob, channel); 7371 7372 test_io_unmap(dev, blob, channel); 7373 7374 spdk_blob_close(blob, blob_op_complete, NULL); 7375 poll_threads(); 7376 CU_ASSERT(g_bserrno == 0); 7377 blob = NULL; 7378 g_blob = NULL; 7379 7380 /* Create thin provisioned blob */ 7381 7382 ut_spdk_blob_opts_init(&opts); 7383 opts.thin_provision = true; 7384 opts.num_clusters = 32; 7385 7386 spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL); 7387 poll_threads(); 7388 CU_ASSERT(g_bserrno == 0); 7389 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7390 blobid = g_blobid; 7391 7392 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 7393 poll_threads(); 7394 CU_ASSERT(g_bserrno == 0); 7395 CU_ASSERT(g_blob != NULL); 7396 blob = g_blob; 7397 7398 test_io_write(dev, blob, channel); 7399 test_io_read(dev, blob, channel); 7400 7401 test_io_zeroes(dev, blob, channel); 7402 7403 test_iov_write(dev, blob, channel); 7404 test_iov_read(dev, blob, channel); 7405 7406 /* Create snapshot */ 7407 7408 spdk_bs_create_snapshot(g_bs, blobid, NULL, blob_op_with_id_complete, NULL); 7409 poll_threads(); 7410 CU_ASSERT(g_bserrno == 0); 7411 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7412 blobid = g_blobid; 7413 7414 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 7415 poll_threads(); 7416 CU_ASSERT(g_bserrno == 0); 7417 CU_ASSERT(g_blob != NULL); 7418 snapshot = g_blob; 7419 7420 spdk_bs_create_clone(g_bs, blobid, NULL, blob_op_with_id_complete, NULL); 7421 poll_threads(); 7422 CU_ASSERT(g_bserrno == 0); 7423 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7424 blobid = g_blobid; 7425 7426 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 7427 poll_threads(); 7428 CU_ASSERT(g_bserrno == 0); 7429 CU_ASSERT(g_blob != NULL); 7430 clone = g_blob; 7431 7432 test_io_read(dev, blob, channel); 7433 test_io_read(dev, snapshot, channel); 7434 test_io_read(dev, clone, channel); 7435 7436 test_iov_read(dev, blob, channel); 7437 test_iov_read(dev, snapshot, channel); 7438 test_iov_read(dev, clone, channel); 7439 7440 /* Inflate clone */ 7441 7442 spdk_bs_inflate_blob(g_bs, channel, blobid, blob_op_complete, NULL); 7443 poll_threads(); 7444 7445 CU_ASSERT(g_bserrno == 0); 7446 7447 test_io_read(dev, clone, channel); 7448 7449 test_io_unmap(dev, clone, channel); 7450 7451 test_iov_write(dev, clone, channel); 7452 test_iov_read(dev, clone, channel); 7453 7454 spdk_blob_close(blob, blob_op_complete, NULL); 7455 spdk_blob_close(snapshot, blob_op_complete, NULL); 7456 spdk_blob_close(clone, blob_op_complete, NULL); 7457 poll_threads(); 7458 CU_ASSERT(g_bserrno == 0); 7459 blob = NULL; 7460 g_blob = NULL; 7461 7462 spdk_bs_free_io_channel(channel); 7463 poll_threads(); 7464 7465 /* Unload the blob store */ 7466 spdk_bs_unload(g_bs, bs_op_complete, NULL); 7467 poll_threads(); 7468 CU_ASSERT(g_bserrno == 0); 7469 g_bs = NULL; 7470 g_blob = NULL; 7471 g_blobid = 0; 7472 } 7473 7474 static void 7475 blob_io_unit_compatiblity(void) 7476 { 7477 struct spdk_bs_opts bsopts; 7478 struct spdk_bs_dev *dev; 7479 struct spdk_bs_super_block *super; 7480 7481 /* Create dev with 512 bytes io unit size */ 7482 7483 spdk_bs_opts_init(&bsopts); 7484 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 7485 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 7486 7487 /* Try to initialize a new blob store with unsupported io_unit */ 7488 dev = init_dev(); 7489 dev->blocklen = 512; 7490 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 7491 7492 /* Initialize a new blob store */ 7493 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 7494 poll_threads(); 7495 CU_ASSERT(g_bserrno == 0); 7496 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7497 7498 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512); 7499 7500 /* Unload the blob store */ 7501 spdk_bs_unload(g_bs, bs_op_complete, NULL); 7502 poll_threads(); 7503 CU_ASSERT(g_bserrno == 0); 7504 7505 /* Modify super block to behave like older version. 7506 * Check if loaded io unit size equals SPDK_BS_PAGE_SIZE */ 7507 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 7508 super->io_unit_size = 0; 7509 super->crc = _spdk_blob_md_page_calc_crc(super); 7510 7511 dev = init_dev(); 7512 dev->blocklen = 512; 7513 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 7514 7515 spdk_bs_load(dev, &bsopts, bs_op_with_handle_complete, NULL); 7516 poll_threads(); 7517 CU_ASSERT(g_bserrno == 0); 7518 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7519 7520 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == SPDK_BS_PAGE_SIZE); 7521 7522 /* Unload the blob store */ 7523 spdk_bs_unload(g_bs, bs_op_complete, NULL); 7524 poll_threads(); 7525 CU_ASSERT(g_bserrno == 0); 7526 7527 g_bs = NULL; 7528 g_blob = NULL; 7529 g_blobid = 0; 7530 } 7531 7532 static void 7533 blob_simultaneous_operations(void) 7534 { 7535 struct spdk_blob_store *bs; 7536 struct spdk_bs_dev *dev; 7537 struct spdk_blob_opts opts; 7538 struct spdk_blob *blob, *snapshot; 7539 spdk_blob_id blobid, snapshotid; 7540 struct spdk_io_channel *channel; 7541 7542 dev = init_dev(); 7543 7544 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 7545 poll_threads(); 7546 CU_ASSERT(g_bserrno == 0); 7547 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7548 bs = g_bs; 7549 7550 channel = spdk_bs_alloc_io_channel(bs); 7551 SPDK_CU_ASSERT_FATAL(channel != NULL); 7552 7553 ut_spdk_blob_opts_init(&opts); 7554 opts.num_clusters = 10; 7555 7556 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 7557 poll_threads(); 7558 CU_ASSERT(g_bserrno == 0); 7559 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7560 blobid = g_blobid; 7561 7562 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7563 poll_threads(); 7564 CU_ASSERT(g_bserrno == 0); 7565 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7566 blob = g_blob; 7567 7568 /* Create snapshot and try to remove blob in the same time: 7569 * - snapshot should be created successfully 7570 * - delete operation should fail w -EBUSY */ 7571 CU_ASSERT(blob->locked_operation_in_progress == false); 7572 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 7573 CU_ASSERT(blob->locked_operation_in_progress == true); 7574 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7575 CU_ASSERT(blob->locked_operation_in_progress == true); 7576 /* Deletion failure */ 7577 CU_ASSERT(g_bserrno == -EBUSY); 7578 poll_threads(); 7579 CU_ASSERT(blob->locked_operation_in_progress == false); 7580 /* Snapshot creation success */ 7581 CU_ASSERT(g_bserrno == 0); 7582 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7583 7584 snapshotid = g_blobid; 7585 7586 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 7587 poll_threads(); 7588 CU_ASSERT(g_bserrno == 0); 7589 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7590 snapshot = g_blob; 7591 7592 /* Inflate blob and try to remove blob in the same time: 7593 * - blob should be inflated successfully 7594 * - delete operation should fail w -EBUSY */ 7595 CU_ASSERT(blob->locked_operation_in_progress == false); 7596 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 7597 CU_ASSERT(blob->locked_operation_in_progress == true); 7598 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7599 CU_ASSERT(blob->locked_operation_in_progress == true); 7600 /* Deletion failure */ 7601 CU_ASSERT(g_bserrno == -EBUSY); 7602 poll_threads(); 7603 CU_ASSERT(blob->locked_operation_in_progress == false); 7604 /* Inflation success */ 7605 CU_ASSERT(g_bserrno == 0); 7606 7607 /* Clone snapshot and try to remove snapshot in the same time: 7608 * - snapshot should be cloned successfully 7609 * - delete operation should fail w -EBUSY */ 7610 CU_ASSERT(blob->locked_operation_in_progress == false); 7611 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 7612 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 7613 /* Deletion failure */ 7614 CU_ASSERT(g_bserrno == -EBUSY); 7615 poll_threads(); 7616 CU_ASSERT(blob->locked_operation_in_progress == false); 7617 /* Clone created */ 7618 CU_ASSERT(g_bserrno == 0); 7619 7620 /* Resize blob and try to remove blob in the same time: 7621 * - blob should be resized successfully 7622 * - delete operation should fail w -EBUSY */ 7623 CU_ASSERT(blob->locked_operation_in_progress == false); 7624 spdk_blob_resize(blob, 50, blob_op_complete, NULL); 7625 CU_ASSERT(blob->locked_operation_in_progress == true); 7626 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7627 CU_ASSERT(blob->locked_operation_in_progress == true); 7628 /* Deletion failure */ 7629 CU_ASSERT(g_bserrno == -EBUSY); 7630 poll_threads(); 7631 CU_ASSERT(blob->locked_operation_in_progress == false); 7632 /* Blob resized successfully */ 7633 CU_ASSERT(g_bserrno == 0); 7634 7635 spdk_blob_close(blob, blob_op_complete, NULL); 7636 poll_threads(); 7637 CU_ASSERT(g_bserrno == 0); 7638 7639 spdk_blob_close(snapshot, blob_op_complete, NULL); 7640 poll_threads(); 7641 CU_ASSERT(g_bserrno == 0); 7642 7643 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7644 poll_threads(); 7645 CU_ASSERT(g_bserrno == 0); 7646 7647 spdk_bs_unload(g_bs, bs_op_complete, NULL); 7648 poll_threads(); 7649 CU_ASSERT(g_bserrno == 0); 7650 g_bs = NULL; 7651 7652 spdk_bs_free_io_channel(channel); 7653 poll_threads(); 7654 } 7655 7656 int main(int argc, char **argv) 7657 { 7658 CU_pSuite suite = NULL; 7659 unsigned int num_failures; 7660 7661 if (CU_initialize_registry() != CUE_SUCCESS) { 7662 return CU_get_error(); 7663 } 7664 7665 suite = CU_add_suite("blob", NULL, NULL); 7666 if (suite == NULL) { 7667 CU_cleanup_registry(); 7668 return CU_get_error(); 7669 } 7670 7671 if ( 7672 CU_add_test(suite, "blob_init", blob_init) == NULL || 7673 CU_add_test(suite, "blob_open", blob_open) == NULL || 7674 CU_add_test(suite, "blob_create", blob_create) == NULL || 7675 CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL || 7676 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 7677 CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL || 7678 CU_add_test(suite, "blob_clone", blob_clone) == NULL || 7679 CU_add_test(suite, "blob_inflate", blob_inflate) == NULL || 7680 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 7681 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 7682 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 7683 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 7684 CU_add_test(suite, "blob_super", blob_super) == NULL || 7685 CU_add_test(suite, "blob_write", blob_write) == NULL || 7686 CU_add_test(suite, "blob_read", blob_read) == NULL || 7687 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 7688 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 7689 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 7690 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 7691 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 7692 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 7693 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 7694 CU_add_test(suite, "bs_load", bs_load) == NULL || 7695 CU_add_test(suite, "bs_load_pending_removal", bs_load_pending_removal) == NULL || 7696 CU_add_test(suite, "bs_load_custom_cluster_size", bs_load_custom_cluster_size) == NULL || 7697 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 7698 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 7699 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 7700 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 7701 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 7702 CU_add_test(suite, "bs_type", bs_type) == NULL || 7703 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 7704 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 7705 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 7706 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 7707 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 7708 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 7709 CU_add_test(suite, "bs_version", bs_version) == NULL || 7710 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 7711 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 7712 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 7713 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 7714 CU_add_test(suite, "blob_thin_prov_rle", blob_thin_prov_rle) == NULL || 7715 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL || 7716 CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL || 7717 CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL || 7718 CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL || 7719 CU_add_test(suite, "blob_relations", blob_relations) == NULL || 7720 CU_add_test(suite, "blob_relations2", blob_relations2) == NULL || 7721 CU_add_test(suite, "blob_delete_snapshot_power_failure", 7722 blob_delete_snapshot_power_failure) == NULL || 7723 CU_add_test(suite, "blob_create_snapshot_power_failure", 7724 blob_create_snapshot_power_failure) == NULL || 7725 CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL || 7726 CU_add_test(suite, "blob_snapshot_freeze_io", blob_snapshot_freeze_io) == NULL || 7727 CU_add_test(suite, "blob_operation_split_rw", blob_operation_split_rw) == NULL || 7728 CU_add_test(suite, "blob_operation_split_rw_iov", blob_operation_split_rw_iov) == NULL || 7729 CU_add_test(suite, "blob_io_unit", blob_io_unit) == NULL || 7730 CU_add_test(suite, "blob_io_unit_compatiblity", blob_io_unit_compatiblity) == NULL || 7731 CU_add_test(suite, "blob_simultaneous_operations", blob_simultaneous_operations) == NULL 7732 ) { 7733 CU_cleanup_registry(); 7734 return CU_get_error(); 7735 } 7736 7737 allocate_threads(2); 7738 set_thread(0); 7739 7740 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 7741 7742 CU_basic_set_mode(CU_BRM_VERBOSE); 7743 g_use_extent_table = false; 7744 CU_basic_run_tests(); 7745 num_failures = CU_get_number_of_failures(); 7746 g_use_extent_table = true; 7747 CU_basic_run_tests(); 7748 num_failures += CU_get_number_of_failures(); 7749 CU_cleanup_registry(); 7750 7751 free(g_dev_buffer); 7752 7753 free_threads(); 7754 7755 return num_failures; 7756 } 7757