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