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