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