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