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