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