1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "spdk_cunit.h" 37 #include "spdk/blob.h" 38 #include "spdk/string.h" 39 #include "spdk_internal/thread.h" 40 41 #include "common/lib/ut_multithread.c" 42 #include "../bs_dev_common.c" 43 #include "blob/blobstore.c" 44 #include "blob/request.c" 45 #include "blob/zeroes.c" 46 #include "blob/blob_bs_dev.c" 47 48 struct spdk_blob_store *g_bs; 49 spdk_blob_id g_blobid; 50 struct spdk_blob *g_blob; 51 int g_bserrno; 52 struct spdk_xattr_names *g_names; 53 int g_done; 54 char *g_xattr_names[] = {"first", "second", "third"}; 55 char *g_xattr_values[] = {"one", "two", "three"}; 56 uint64_t g_ctx = 1729; 57 58 struct spdk_bs_super_block_ver1 { 59 uint8_t signature[8]; 60 uint32_t version; 61 uint32_t length; 62 uint32_t clean; /* If there was a clean shutdown, this is 1. */ 63 spdk_blob_id super_blob; 64 65 uint32_t cluster_size; /* In bytes */ 66 67 uint32_t used_page_mask_start; /* Offset from beginning of disk, in pages */ 68 uint32_t used_page_mask_len; /* Count, in pages */ 69 70 uint32_t used_cluster_mask_start; /* Offset from beginning of disk, in pages */ 71 uint32_t used_cluster_mask_len; /* Count, in pages */ 72 73 uint32_t md_start; /* Offset from beginning of disk, in pages */ 74 uint32_t md_len; /* Count, in pages */ 75 76 uint8_t reserved[4036]; 77 uint32_t crc; 78 } __attribute__((packed)); 79 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size"); 80 81 static void 82 _get_xattr_value(void *arg, const char *name, 83 const void **value, size_t *value_len) 84 { 85 uint64_t i; 86 87 SPDK_CU_ASSERT_FATAL(value_len != NULL); 88 SPDK_CU_ASSERT_FATAL(value != NULL); 89 CU_ASSERT(arg == &g_ctx) 90 91 for (i = 0; i < sizeof(g_xattr_names); i++) { 92 if (!strcmp(name, g_xattr_names[i])) { 93 *value_len = strlen(g_xattr_values[i]); 94 *value = g_xattr_values[i]; 95 break; 96 } 97 } 98 } 99 100 static void 101 _get_xattr_value_null(void *arg, const char *name, 102 const void **value, size_t *value_len) 103 { 104 SPDK_CU_ASSERT_FATAL(value_len != NULL); 105 SPDK_CU_ASSERT_FATAL(value != NULL); 106 CU_ASSERT(arg == NULL) 107 108 *value_len = 0; 109 *value = NULL; 110 } 111 112 static int 113 _get_snapshots_count(struct spdk_blob_store *bs) 114 { 115 struct spdk_blob_list *snapshot = NULL; 116 int count = 0; 117 118 TAILQ_FOREACH(snapshot, &bs->snapshots, link) { 119 count += 1; 120 } 121 122 return count; 123 } 124 125 static void 126 bs_op_complete(void *cb_arg, int bserrno) 127 { 128 g_bserrno = bserrno; 129 } 130 131 static void 132 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 133 int bserrno) 134 { 135 g_bs = bs; 136 g_bserrno = bserrno; 137 } 138 139 static void 140 blob_op_complete(void *cb_arg, int bserrno) 141 { 142 g_bserrno = bserrno; 143 } 144 145 static void 146 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 147 { 148 g_blobid = blobid; 149 g_bserrno = bserrno; 150 } 151 152 static void 153 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 154 { 155 g_blob = blb; 156 g_bserrno = bserrno; 157 } 158 159 static void 160 blob_init(void) 161 { 162 struct spdk_bs_dev *dev; 163 164 dev = init_dev(); 165 166 /* should fail for an unsupported blocklen */ 167 dev->blocklen = 500; 168 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 169 poll_threads(); 170 CU_ASSERT(g_bserrno == -EINVAL); 171 172 dev = init_dev(); 173 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 174 poll_threads(); 175 CU_ASSERT(g_bserrno == 0); 176 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 177 178 spdk_bs_unload(g_bs, bs_op_complete, NULL); 179 poll_threads(); 180 CU_ASSERT(g_bserrno == 0); 181 g_bs = NULL; 182 } 183 184 static void 185 blob_super(void) 186 { 187 struct spdk_blob_store *bs; 188 struct spdk_bs_dev *dev; 189 spdk_blob_id blobid; 190 191 dev = init_dev(); 192 193 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 194 poll_threads(); 195 CU_ASSERT(g_bserrno == 0); 196 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 197 bs = g_bs; 198 199 /* Get the super blob without having set one */ 200 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 201 poll_threads(); 202 CU_ASSERT(g_bserrno == -ENOENT); 203 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 204 205 /* Create a blob */ 206 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 207 poll_threads(); 208 CU_ASSERT(g_bserrno == 0); 209 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 210 blobid = g_blobid; 211 212 /* Set the blob as the super blob */ 213 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 214 poll_threads(); 215 CU_ASSERT(g_bserrno == 0); 216 217 /* Get the super blob */ 218 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 219 poll_threads(); 220 CU_ASSERT(g_bserrno == 0); 221 CU_ASSERT(blobid == g_blobid); 222 223 spdk_bs_unload(g_bs, bs_op_complete, NULL); 224 poll_threads(); 225 CU_ASSERT(g_bserrno == 0); 226 g_bs = NULL; 227 } 228 229 static void 230 blob_open(void) 231 { 232 struct spdk_blob_store *bs; 233 struct spdk_bs_dev *dev; 234 struct spdk_blob *blob; 235 spdk_blob_id blobid, blobid2; 236 237 dev = init_dev(); 238 239 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 240 poll_threads(); 241 CU_ASSERT(g_bserrno == 0); 242 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 243 bs = g_bs; 244 245 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 246 poll_threads(); 247 CU_ASSERT(g_bserrno == 0); 248 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 249 blobid = g_blobid; 250 251 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 252 poll_threads(); 253 CU_ASSERT(g_bserrno == 0); 254 CU_ASSERT(g_blob != NULL); 255 blob = g_blob; 256 257 blobid2 = spdk_blob_get_id(blob); 258 CU_ASSERT(blobid == blobid2); 259 260 /* Try to open file again. It should return success. */ 261 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 262 poll_threads(); 263 CU_ASSERT(g_bserrno == 0); 264 CU_ASSERT(blob == g_blob); 265 266 spdk_blob_close(blob, blob_op_complete, NULL); 267 poll_threads(); 268 CU_ASSERT(g_bserrno == 0); 269 270 /* 271 * Close the file a second time, releasing the second reference. This 272 * should succeed. 273 */ 274 blob = g_blob; 275 spdk_blob_close(blob, blob_op_complete, NULL); 276 poll_threads(); 277 CU_ASSERT(g_bserrno == 0); 278 279 /* 280 * Try to open file again. It should succeed. This tests the case 281 * where the file is opened, closed, then re-opened again. 282 */ 283 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 284 poll_threads(); 285 CU_ASSERT(g_bserrno == 0); 286 CU_ASSERT(g_blob != NULL); 287 blob = g_blob; 288 289 spdk_blob_close(blob, blob_op_complete, NULL); 290 poll_threads(); 291 CU_ASSERT(g_bserrno == 0); 292 293 spdk_bs_unload(g_bs, bs_op_complete, NULL); 294 poll_threads(); 295 CU_ASSERT(g_bserrno == 0); 296 g_bs = NULL; 297 } 298 299 static void 300 blob_create(void) 301 { 302 struct spdk_blob_store *bs; 303 struct spdk_bs_dev *dev; 304 struct spdk_blob *blob; 305 struct spdk_blob_opts opts; 306 spdk_blob_id blobid; 307 308 dev = init_dev(); 309 310 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 311 poll_threads(); 312 CU_ASSERT(g_bserrno == 0); 313 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 314 bs = g_bs; 315 316 /* Create blob with 10 clusters */ 317 318 spdk_blob_opts_init(&opts); 319 opts.num_clusters = 10; 320 321 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 322 poll_threads(); 323 CU_ASSERT(g_bserrno == 0); 324 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 325 blobid = g_blobid; 326 327 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 328 poll_threads(); 329 CU_ASSERT(g_bserrno == 0); 330 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 331 blob = g_blob; 332 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 333 334 spdk_blob_close(blob, blob_op_complete, NULL); 335 poll_threads(); 336 CU_ASSERT(g_bserrno == 0); 337 338 /* Create blob with 0 clusters */ 339 340 spdk_blob_opts_init(&opts); 341 opts.num_clusters = 0; 342 343 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 344 poll_threads(); 345 CU_ASSERT(g_bserrno == 0); 346 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 347 blobid = g_blobid; 348 349 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 350 poll_threads(); 351 CU_ASSERT(g_bserrno == 0); 352 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 353 blob = g_blob; 354 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 355 356 spdk_blob_close(blob, blob_op_complete, NULL); 357 poll_threads(); 358 CU_ASSERT(g_bserrno == 0); 359 360 /* Create blob with default options (opts == NULL) */ 361 362 spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL); 363 poll_threads(); 364 CU_ASSERT(g_bserrno == 0); 365 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 366 blobid = g_blobid; 367 368 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 369 poll_threads(); 370 CU_ASSERT(g_bserrno == 0); 371 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 372 blob = g_blob; 373 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 374 375 spdk_blob_close(blob, blob_op_complete, NULL); 376 poll_threads(); 377 CU_ASSERT(g_bserrno == 0); 378 379 /* Try to create blob with size larger than blobstore */ 380 381 spdk_blob_opts_init(&opts); 382 opts.num_clusters = bs->total_clusters + 1; 383 384 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 385 poll_threads(); 386 CU_ASSERT(g_bserrno == -ENOSPC); 387 388 spdk_bs_unload(g_bs, bs_op_complete, NULL); 389 poll_threads(); 390 CU_ASSERT(g_bserrno == 0); 391 g_bs = NULL; 392 393 } 394 395 static void 396 blob_create_internal(void) 397 { 398 struct spdk_blob_store *bs; 399 struct spdk_bs_dev *dev; 400 struct spdk_blob *blob; 401 struct spdk_blob_opts opts; 402 struct spdk_blob_xattr_opts internal_xattrs; 403 const void *value; 404 size_t value_len; 405 spdk_blob_id blobid; 406 int rc; 407 408 dev = init_dev(); 409 410 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 411 poll_threads(); 412 CU_ASSERT(g_bserrno == 0); 413 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 414 bs = g_bs; 415 416 /* Create blob with custom xattrs */ 417 418 spdk_blob_opts_init(&opts); 419 _spdk_blob_xattrs_init(&internal_xattrs); 420 internal_xattrs.count = 3; 421 internal_xattrs.names = g_xattr_names; 422 internal_xattrs.get_value = _get_xattr_value; 423 internal_xattrs.ctx = &g_ctx; 424 425 _spdk_bs_create_blob(bs, &opts, &internal_xattrs, blob_op_with_id_complete, NULL); 426 poll_threads(); 427 CU_ASSERT(g_bserrno == 0); 428 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 429 blobid = g_blobid; 430 431 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 432 poll_threads(); 433 CU_ASSERT(g_bserrno == 0); 434 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 435 blob = g_blob; 436 437 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len, true); 438 CU_ASSERT(rc == 0); 439 SPDK_CU_ASSERT_FATAL(value != NULL); 440 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 441 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 442 443 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len, true); 444 CU_ASSERT(rc == 0); 445 SPDK_CU_ASSERT_FATAL(value != NULL); 446 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 447 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 448 449 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len, true); 450 CU_ASSERT(rc == 0); 451 SPDK_CU_ASSERT_FATAL(value != NULL); 452 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 453 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 454 455 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 456 CU_ASSERT(rc != 0); 457 458 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 459 CU_ASSERT(rc != 0); 460 461 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 462 CU_ASSERT(rc != 0); 463 464 spdk_blob_close(blob, blob_op_complete, NULL); 465 poll_threads(); 466 CU_ASSERT(g_bserrno == 0); 467 468 /* Create blob with NULL internal options */ 469 470 _spdk_bs_create_blob(bs, NULL, NULL, blob_op_with_id_complete, NULL); 471 poll_threads(); 472 CU_ASSERT(g_bserrno == 0); 473 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 474 blobid = g_blobid; 475 476 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 477 poll_threads(); 478 CU_ASSERT(g_bserrno == 0); 479 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 480 CU_ASSERT(TAILQ_FIRST(&g_blob->xattrs_internal) == NULL); 481 482 blob = g_blob; 483 484 spdk_blob_close(blob, blob_op_complete, NULL); 485 poll_threads(); 486 CU_ASSERT(g_bserrno == 0); 487 488 spdk_bs_unload(g_bs, bs_op_complete, NULL); 489 poll_threads(); 490 CU_ASSERT(g_bserrno == 0); 491 g_bs = NULL; 492 493 } 494 495 static void 496 blob_thin_provision(void) 497 { 498 struct spdk_blob_store *bs; 499 struct spdk_bs_dev *dev; 500 struct spdk_blob *blob; 501 struct spdk_blob_opts opts; 502 struct spdk_bs_opts bs_opts; 503 spdk_blob_id blobid; 504 505 dev = init_dev(); 506 spdk_bs_opts_init(&bs_opts); 507 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 508 509 /* Initialize a new blob store */ 510 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 511 poll_threads(); 512 CU_ASSERT(g_bserrno == 0); 513 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 514 515 bs = g_bs; 516 517 /* Create blob with thin provisioning enabled */ 518 519 spdk_blob_opts_init(&opts); 520 opts.thin_provision = true; 521 opts.num_clusters = 10; 522 523 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 524 poll_threads(); 525 CU_ASSERT(g_bserrno == 0); 526 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 527 blobid = g_blobid; 528 529 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 530 poll_threads(); 531 CU_ASSERT(g_bserrno == 0); 532 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 533 blob = g_blob; 534 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 535 536 spdk_blob_close(blob, blob_op_complete, NULL); 537 CU_ASSERT(g_bserrno == 0); 538 539 /* Do not shut down cleanly. This makes sure that when we load again 540 * and try to recover a valid used_cluster map, that blobstore will 541 * ignore clusters with index 0 since these are unallocated clusters. 542 */ 543 544 /* Load an existing blob store and check if invalid_flags is set */ 545 dev = init_dev(); 546 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 547 spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL); 548 poll_threads(); 549 CU_ASSERT(g_bserrno == 0); 550 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 551 552 bs = g_bs; 553 554 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 555 poll_threads(); 556 CU_ASSERT(g_bserrno == 0); 557 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 558 blob = g_blob; 559 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 560 561 spdk_blob_close(blob, blob_op_complete, NULL); 562 poll_threads(); 563 CU_ASSERT(g_bserrno == 0); 564 565 spdk_bs_unload(g_bs, bs_op_complete, NULL); 566 poll_threads(); 567 CU_ASSERT(g_bserrno == 0); 568 g_bs = NULL; 569 } 570 571 static void 572 blob_snapshot(void) 573 { 574 struct spdk_blob_store *bs; 575 struct spdk_bs_dev *dev; 576 struct spdk_blob *blob; 577 struct spdk_blob *snapshot, *snapshot2; 578 struct spdk_blob_bs_dev *blob_bs_dev; 579 struct spdk_blob_opts opts; 580 struct spdk_blob_xattr_opts xattrs; 581 spdk_blob_id blobid; 582 spdk_blob_id snapshotid; 583 spdk_blob_id snapshotid2; 584 const void *value; 585 size_t value_len; 586 int rc; 587 588 dev = init_dev(); 589 590 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 591 poll_threads(); 592 CU_ASSERT(g_bserrno == 0); 593 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 594 bs = g_bs; 595 596 /* Create blob with 10 clusters */ 597 spdk_blob_opts_init(&opts); 598 opts.num_clusters = 10; 599 600 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 601 poll_threads(); 602 CU_ASSERT(g_bserrno == 0); 603 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 604 blobid = g_blobid; 605 606 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 607 poll_threads(); 608 CU_ASSERT(g_bserrno == 0); 609 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 610 blob = g_blob; 611 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 612 613 /* Create snapshot from blob */ 614 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 0); 615 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 616 poll_threads(); 617 CU_ASSERT(g_bserrno == 0); 618 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 619 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1); 620 snapshotid = g_blobid; 621 622 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 623 poll_threads(); 624 CU_ASSERT(g_bserrno == 0); 625 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 626 snapshot = g_blob; 627 CU_ASSERT(snapshot->data_ro == true) 628 CU_ASSERT(snapshot->md_ro == true) 629 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10) 630 631 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 632 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 633 CU_ASSERT(spdk_mem_all_zero(blob->active.clusters, 634 blob->active.num_clusters * sizeof(blob->active.clusters[0]))); 635 636 /* Try to create snapshot from clone with xattrs */ 637 xattrs.names = g_xattr_names; 638 xattrs.get_value = _get_xattr_value; 639 xattrs.count = 3; 640 xattrs.ctx = &g_ctx; 641 spdk_bs_create_snapshot(bs, blobid, &xattrs, blob_op_with_id_complete, NULL); 642 poll_threads(); 643 CU_ASSERT(g_bserrno == 0); 644 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 645 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2); 646 snapshotid2 = g_blobid; 647 648 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 649 CU_ASSERT(g_bserrno == 0); 650 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 651 snapshot2 = g_blob; 652 CU_ASSERT(snapshot2->data_ro == true) 653 CU_ASSERT(snapshot2->md_ro == true) 654 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 10) 655 656 /* Confirm that blob is backed by snapshot2 and snapshot2 is backed by snapshot */ 657 CU_ASSERT(snapshot->back_bs_dev == NULL); 658 SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL); 659 SPDK_CU_ASSERT_FATAL(snapshot2->back_bs_dev != NULL); 660 661 blob_bs_dev = (struct spdk_blob_bs_dev *)blob->back_bs_dev; 662 CU_ASSERT(blob_bs_dev->blob == snapshot2); 663 664 blob_bs_dev = (struct spdk_blob_bs_dev *)snapshot2->back_bs_dev; 665 CU_ASSERT(blob_bs_dev->blob == snapshot); 666 667 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[0], &value, &value_len); 668 CU_ASSERT(rc == 0); 669 SPDK_CU_ASSERT_FATAL(value != NULL); 670 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 671 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 672 673 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[1], &value, &value_len); 674 CU_ASSERT(rc == 0); 675 SPDK_CU_ASSERT_FATAL(value != NULL); 676 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 677 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 678 679 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[2], &value, &value_len); 680 CU_ASSERT(rc == 0); 681 SPDK_CU_ASSERT_FATAL(value != NULL); 682 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 683 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 684 685 /* Try to create snapshot from snapshot */ 686 spdk_bs_create_snapshot(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 687 poll_threads(); 688 CU_ASSERT(g_bserrno == -EINVAL); 689 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 690 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2); 691 692 spdk_blob_close(blob, blob_op_complete, NULL); 693 poll_threads(); 694 CU_ASSERT(g_bserrno == 0); 695 696 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 697 CU_ASSERT(g_bserrno == 0); 698 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2); 699 700 spdk_blob_close(snapshot2, blob_op_complete, NULL); 701 poll_threads(); 702 CU_ASSERT(g_bserrno == 0); 703 704 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 705 poll_threads(); 706 CU_ASSERT(g_bserrno == 0); 707 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1); 708 709 spdk_blob_close(snapshot, blob_op_complete, NULL); 710 poll_threads(); 711 CU_ASSERT(g_bserrno == 0); 712 713 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 714 poll_threads(); 715 CU_ASSERT(g_bserrno == 0); 716 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 0); 717 718 spdk_bs_unload(g_bs, bs_op_complete, NULL); 719 poll_threads(); 720 CU_ASSERT(g_bserrno == 0); 721 g_bs = NULL; 722 } 723 724 static void 725 blob_snapshot_freeze_io(void) 726 { 727 struct spdk_thread *thread; 728 struct spdk_io_channel *channel; 729 struct spdk_bs_channel *bs_channel; 730 struct spdk_blob_store *bs; 731 struct spdk_bs_dev *dev; 732 struct spdk_blob *blob; 733 struct spdk_blob_opts opts; 734 spdk_blob_id blobid; 735 uint32_t num_of_pages = 10; 736 uint8_t payload_read[num_of_pages * SPDK_BS_PAGE_SIZE]; 737 uint8_t payload_write[num_of_pages * SPDK_BS_PAGE_SIZE]; 738 uint8_t payload_zero[num_of_pages * SPDK_BS_PAGE_SIZE]; 739 740 memset(payload_write, 0xE5, sizeof(payload_write)); 741 memset(payload_read, 0x00, sizeof(payload_read)); 742 memset(payload_zero, 0x00, sizeof(payload_zero)); 743 744 dev = init_dev(); 745 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 746 747 /* Test freeze I/O during snapshot */ 748 749 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 750 poll_threads(); 751 CU_ASSERT(g_bserrno == 0); 752 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 753 bs = g_bs; 754 755 channel = spdk_bs_alloc_io_channel(bs); 756 bs_channel = spdk_io_channel_get_ctx(channel); 757 758 /* Create blob with 10 clusters */ 759 spdk_blob_opts_init(&opts); 760 opts.num_clusters = 10; 761 opts.thin_provision = false; 762 763 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 764 poll_threads(); 765 CU_ASSERT(g_bserrno == 0); 766 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 767 blobid = g_blobid; 768 769 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 770 poll_threads(); 771 CU_ASSERT(g_bserrno == 0); 772 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 773 blob = g_blob; 774 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 775 776 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 777 778 /* This is implementation specific. 779 * Flag 'frozen_io' is set in _spdk_bs_snapshot_freeze_cpl callback. 780 * Four async I/O operations happen before that. */ 781 thread = spdk_get_thread(); 782 spdk_set_thread(NULL); 783 spdk_thread_poll(thread, 1); 784 spdk_thread_poll(thread, 1); 785 spdk_thread_poll(thread, 1); 786 spdk_set_thread(thread); 787 788 CU_ASSERT(TAILQ_EMPTY(&bs_channel->queued_io)); 789 790 /* Blob I/O should be frozen here */ 791 CU_ASSERT(blob->frozen_refcnt == 1); 792 793 /* Write to the blob */ 794 spdk_blob_io_write(blob, channel, payload_write, 0, num_of_pages, blob_op_complete, NULL); 795 796 /* Verify that I/O is queued */ 797 CU_ASSERT(!TAILQ_EMPTY(&bs_channel->queued_io)); 798 /* Verify that payload is not written to disk */ 799 CU_ASSERT(memcmp(payload_zero, &g_dev_buffer[blob->active.clusters[0]*SPDK_BS_PAGE_SIZE], 800 SPDK_BS_PAGE_SIZE) == 0); 801 802 /* Finish all operations including spdk_bs_create_snapshot */ 803 poll_threads(); 804 805 /* Verify snapshot */ 806 CU_ASSERT(g_bserrno == 0); 807 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 808 809 /* Verify that blob has unset frozen_io */ 810 CU_ASSERT(blob->frozen_refcnt == 0); 811 812 /* Verify that postponed I/O completed successfully by comparing payload */ 813 spdk_blob_io_read(blob, channel, payload_read, 0, num_of_pages, blob_op_complete, NULL); 814 poll_threads(); 815 CU_ASSERT(g_bserrno == 0); 816 CU_ASSERT(memcmp(payload_write, payload_read, num_of_pages * SPDK_BS_PAGE_SIZE) == 0); 817 818 spdk_blob_close(blob, blob_op_complete, NULL); 819 poll_threads(); 820 CU_ASSERT(g_bserrno == 0); 821 822 spdk_bs_free_io_channel(channel); 823 poll_threads(); 824 825 spdk_bs_unload(g_bs, bs_op_complete, NULL); 826 poll_threads(); 827 CU_ASSERT(g_bserrno == 0); 828 g_bs = NULL; 829 } 830 831 static void 832 blob_clone(void) 833 { 834 struct spdk_blob_store *bs; 835 struct spdk_bs_dev *dev; 836 struct spdk_blob_opts opts; 837 struct spdk_blob *blob, *snapshot, *clone; 838 spdk_blob_id blobid, cloneid, snapshotid; 839 struct spdk_blob_xattr_opts xattrs; 840 const void *value; 841 size_t value_len; 842 int rc; 843 844 dev = init_dev(); 845 846 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 847 poll_threads(); 848 CU_ASSERT(g_bserrno == 0); 849 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 850 bs = g_bs; 851 852 /* Create blob with 10 clusters */ 853 854 spdk_blob_opts_init(&opts); 855 opts.num_clusters = 10; 856 857 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 858 poll_threads(); 859 CU_ASSERT(g_bserrno == 0); 860 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 861 blobid = g_blobid; 862 863 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 864 poll_threads(); 865 CU_ASSERT(g_bserrno == 0); 866 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 867 blob = g_blob; 868 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 869 870 /* Create snapshot */ 871 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 872 poll_threads(); 873 CU_ASSERT(g_bserrno == 0); 874 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 875 snapshotid = g_blobid; 876 877 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 878 poll_threads(); 879 CU_ASSERT(g_bserrno == 0); 880 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 881 snapshot = g_blob; 882 CU_ASSERT(snapshot->data_ro == true) 883 CU_ASSERT(snapshot->md_ro == true) 884 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 885 886 spdk_blob_close(snapshot, blob_op_complete, NULL); 887 poll_threads(); 888 CU_ASSERT(g_bserrno == 0); 889 890 /* Create clone from snapshot with xattrs */ 891 xattrs.names = g_xattr_names; 892 xattrs.get_value = _get_xattr_value; 893 xattrs.count = 3; 894 xattrs.ctx = &g_ctx; 895 896 spdk_bs_create_clone(bs, snapshotid, &xattrs, blob_op_with_id_complete, NULL); 897 poll_threads(); 898 CU_ASSERT(g_bserrno == 0); 899 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 900 cloneid = g_blobid; 901 902 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 903 poll_threads(); 904 CU_ASSERT(g_bserrno == 0); 905 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 906 clone = g_blob; 907 CU_ASSERT(clone->data_ro == false) 908 CU_ASSERT(clone->md_ro == false) 909 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 910 911 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[0], &value, &value_len); 912 CU_ASSERT(rc == 0); 913 SPDK_CU_ASSERT_FATAL(value != NULL); 914 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 915 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 916 917 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[1], &value, &value_len); 918 CU_ASSERT(rc == 0); 919 SPDK_CU_ASSERT_FATAL(value != NULL); 920 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 921 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 922 923 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[2], &value, &value_len); 924 CU_ASSERT(rc == 0); 925 SPDK_CU_ASSERT_FATAL(value != NULL); 926 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 927 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 928 929 930 spdk_blob_close(clone, blob_op_complete, NULL); 931 poll_threads(); 932 CU_ASSERT(g_bserrno == 0); 933 934 /* Try to create clone from not read only blob */ 935 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 936 poll_threads(); 937 CU_ASSERT(g_bserrno == -EINVAL); 938 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 939 940 /* Mark blob as read only */ 941 spdk_blob_set_read_only(blob); 942 spdk_blob_sync_md(blob, blob_op_complete, NULL); 943 poll_threads(); 944 CU_ASSERT(g_bserrno == 0); 945 946 /* Create clone from read only blob */ 947 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 948 poll_threads(); 949 CU_ASSERT(g_bserrno == 0); 950 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 951 cloneid = g_blobid; 952 953 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 954 poll_threads(); 955 CU_ASSERT(g_bserrno == 0); 956 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 957 clone = g_blob; 958 CU_ASSERT(clone->data_ro == false) 959 CU_ASSERT(clone->md_ro == false) 960 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 961 962 spdk_blob_close(clone, blob_op_complete, NULL); 963 poll_threads(); 964 CU_ASSERT(g_bserrno == 0); 965 966 spdk_blob_close(blob, blob_op_complete, NULL); 967 poll_threads(); 968 CU_ASSERT(g_bserrno == 0); 969 970 spdk_bs_unload(g_bs, bs_op_complete, NULL); 971 poll_threads(); 972 CU_ASSERT(g_bserrno == 0); 973 g_bs = NULL; 974 975 } 976 977 static void 978 _blob_inflate(bool decouple_parent) 979 { 980 struct spdk_blob_store *bs; 981 struct spdk_bs_dev *dev; 982 struct spdk_blob_opts opts; 983 struct spdk_blob *blob, *snapshot; 984 spdk_blob_id blobid, snapshotid; 985 struct spdk_io_channel *channel; 986 uint64_t free_clusters; 987 988 dev = init_dev(); 989 990 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 991 poll_threads(); 992 CU_ASSERT(g_bserrno == 0); 993 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 994 bs = g_bs; 995 996 channel = spdk_bs_alloc_io_channel(bs); 997 SPDK_CU_ASSERT_FATAL(channel != NULL); 998 999 /* Create blob with 10 clusters */ 1000 1001 spdk_blob_opts_init(&opts); 1002 opts.num_clusters = 10; 1003 opts.thin_provision = true; 1004 1005 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1006 poll_threads(); 1007 CU_ASSERT(g_bserrno == 0); 1008 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1009 blobid = g_blobid; 1010 1011 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1012 poll_threads(); 1013 CU_ASSERT(g_bserrno == 0); 1014 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1015 blob = g_blob; 1016 1017 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 1018 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true); 1019 1020 /* 1) Blob with no parent */ 1021 if (decouple_parent) { 1022 /* Decouple parent of blob with no parent (should fail) */ 1023 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 1024 poll_threads(); 1025 CU_ASSERT(g_bserrno != 0); 1026 } else { 1027 /* Inflate of thin blob with no parent should made it thick */ 1028 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 1029 poll_threads(); 1030 CU_ASSERT(g_bserrno == 0); 1031 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false); 1032 } 1033 1034 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 1035 poll_threads(); 1036 CU_ASSERT(g_bserrno == 0); 1037 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1038 snapshotid = g_blobid; 1039 1040 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true); 1041 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 1042 1043 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 1044 poll_threads(); 1045 CU_ASSERT(g_bserrno == 0); 1046 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1047 snapshot = g_blob; 1048 CU_ASSERT(snapshot->data_ro == true) 1049 CU_ASSERT(snapshot->md_ro == true) 1050 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 1051 1052 spdk_blob_close(snapshot, blob_op_complete, NULL); 1053 poll_threads(); 1054 CU_ASSERT(g_bserrno == 0); 1055 1056 free_clusters = spdk_bs_free_cluster_count(bs); 1057 1058 /* 2) Blob with parent */ 1059 if (!decouple_parent) { 1060 /* Do full blob inflation */ 1061 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 1062 poll_threads(); 1063 CU_ASSERT(g_bserrno == 0); 1064 /* all 10 clusters should be allocated */ 1065 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 10); 1066 } else { 1067 /* Decouple parent of blob */ 1068 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 1069 poll_threads(); 1070 CU_ASSERT(g_bserrno == 0); 1071 /* when only parent is removed, none of the clusters should be allocated */ 1072 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters); 1073 } 1074 1075 /* Now, it should be possible to delete snapshot */ 1076 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 1077 poll_threads(); 1078 CU_ASSERT(g_bserrno == 0); 1079 1080 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 1081 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == decouple_parent); 1082 1083 spdk_blob_close(blob, blob_op_complete, NULL); 1084 poll_threads(); 1085 CU_ASSERT(g_bserrno == 0); 1086 1087 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1088 poll_threads(); 1089 CU_ASSERT(g_bserrno == 0); 1090 g_bs = NULL; 1091 1092 spdk_bs_free_io_channel(channel); 1093 poll_threads(); 1094 } 1095 1096 static void 1097 blob_inflate(void) 1098 { 1099 _blob_inflate(false); 1100 _blob_inflate(true); 1101 } 1102 1103 static void 1104 blob_delete(void) 1105 { 1106 struct spdk_blob_store *bs; 1107 struct spdk_bs_dev *dev; 1108 spdk_blob_id blobid; 1109 1110 dev = init_dev(); 1111 1112 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1113 poll_threads(); 1114 CU_ASSERT(g_bserrno == 0); 1115 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1116 bs = g_bs; 1117 1118 /* Create a blob and then delete it. */ 1119 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1120 poll_threads(); 1121 CU_ASSERT(g_bserrno == 0); 1122 CU_ASSERT(g_blobid > 0); 1123 blobid = g_blobid; 1124 1125 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 1126 poll_threads(); 1127 CU_ASSERT(g_bserrno == 0); 1128 1129 /* Try to open the blob */ 1130 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1131 poll_threads(); 1132 CU_ASSERT(g_bserrno == -ENOENT); 1133 1134 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1135 poll_threads(); 1136 CU_ASSERT(g_bserrno == 0); 1137 g_bs = NULL; 1138 } 1139 1140 static void 1141 blob_resize(void) 1142 { 1143 struct spdk_blob_store *bs; 1144 struct spdk_bs_dev *dev; 1145 struct spdk_blob *blob; 1146 spdk_blob_id blobid; 1147 uint64_t free_clusters; 1148 1149 dev = init_dev(); 1150 1151 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1152 poll_threads(); 1153 CU_ASSERT(g_bserrno == 0); 1154 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1155 bs = g_bs; 1156 free_clusters = spdk_bs_free_cluster_count(bs); 1157 1158 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1159 poll_threads(); 1160 CU_ASSERT(g_bserrno == 0); 1161 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1162 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 1163 blobid = g_blobid; 1164 1165 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1166 poll_threads(); 1167 CU_ASSERT(g_bserrno == 0); 1168 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1169 blob = g_blob; 1170 1171 /* Confirm that resize fails if blob is marked read-only. */ 1172 blob->md_ro = true; 1173 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1174 poll_threads(); 1175 CU_ASSERT(g_bserrno == -EPERM); 1176 blob->md_ro = false; 1177 1178 /* The blob started at 0 clusters. Resize it to be 5. */ 1179 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1180 poll_threads(); 1181 CU_ASSERT(g_bserrno == 0); 1182 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 1183 1184 /* Shrink the blob to 3 clusters. This will not actually release 1185 * the old clusters until the blob is synced. 1186 */ 1187 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 1188 poll_threads(); 1189 CU_ASSERT(g_bserrno == 0); 1190 /* Verify there are still 5 clusters in use */ 1191 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 1192 1193 spdk_blob_sync_md(blob, blob_op_complete, NULL); 1194 poll_threads(); 1195 CU_ASSERT(g_bserrno == 0); 1196 /* Now there are only 3 clusters in use */ 1197 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 1198 1199 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 1200 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 1201 poll_threads(); 1202 CU_ASSERT(g_bserrno == 0); 1203 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 1204 1205 /* Try to resize the blob to size larger than blobstore. */ 1206 spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL); 1207 poll_threads(); 1208 CU_ASSERT(g_bserrno == -ENOSPC); 1209 1210 spdk_blob_close(blob, blob_op_complete, NULL); 1211 poll_threads(); 1212 CU_ASSERT(g_bserrno == 0); 1213 1214 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 1215 poll_threads(); 1216 CU_ASSERT(g_bserrno == 0); 1217 1218 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1219 poll_threads(); 1220 CU_ASSERT(g_bserrno == 0); 1221 g_bs = NULL; 1222 } 1223 1224 static void 1225 blob_read_only(void) 1226 { 1227 struct spdk_blob_store *bs; 1228 struct spdk_bs_dev *dev; 1229 struct spdk_blob *blob; 1230 struct spdk_bs_opts opts; 1231 spdk_blob_id blobid; 1232 int rc; 1233 1234 dev = init_dev(); 1235 spdk_bs_opts_init(&opts); 1236 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1237 1238 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1239 poll_threads(); 1240 CU_ASSERT(g_bserrno == 0); 1241 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1242 bs = g_bs; 1243 1244 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1245 poll_threads(); 1246 CU_ASSERT(g_bserrno == 0); 1247 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1248 blobid = g_blobid; 1249 1250 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1251 poll_threads(); 1252 CU_ASSERT(g_bserrno == 0); 1253 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1254 blob = g_blob; 1255 1256 rc = spdk_blob_set_read_only(blob); 1257 CU_ASSERT(rc == 0); 1258 1259 CU_ASSERT(blob->data_ro == false); 1260 CU_ASSERT(blob->md_ro == false); 1261 1262 spdk_blob_sync_md(blob, bs_op_complete, NULL); 1263 poll_threads(); 1264 1265 CU_ASSERT(blob->data_ro == true); 1266 CU_ASSERT(blob->md_ro == true); 1267 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1268 1269 spdk_blob_close(blob, blob_op_complete, NULL); 1270 poll_threads(); 1271 CU_ASSERT(g_bserrno == 0); 1272 1273 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1274 poll_threads(); 1275 CU_ASSERT(g_bserrno == 0); 1276 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1277 blob = g_blob; 1278 1279 CU_ASSERT(blob->data_ro == true); 1280 CU_ASSERT(blob->md_ro == true); 1281 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1282 1283 spdk_blob_close(blob, blob_op_complete, NULL); 1284 poll_threads(); 1285 CU_ASSERT(g_bserrno == 0); 1286 1287 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1288 poll_threads(); 1289 CU_ASSERT(g_bserrno == 0); 1290 g_bs = NULL; 1291 g_blob = NULL; 1292 g_blobid = 0; 1293 1294 /* Load an existing blob store */ 1295 dev = init_dev(); 1296 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1297 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1298 poll_threads(); 1299 CU_ASSERT(g_bserrno == 0); 1300 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1301 1302 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1303 poll_threads(); 1304 CU_ASSERT(g_bserrno == 0); 1305 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1306 blob = g_blob; 1307 1308 CU_ASSERT(blob->data_ro == true); 1309 CU_ASSERT(blob->md_ro == true); 1310 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1311 1312 spdk_blob_close(blob, blob_op_complete, NULL); 1313 poll_threads(); 1314 CU_ASSERT(g_bserrno == 0); 1315 1316 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1317 poll_threads(); 1318 CU_ASSERT(g_bserrno == 0); 1319 1320 } 1321 1322 static void 1323 channel_ops(void) 1324 { 1325 struct spdk_blob_store *bs; 1326 struct spdk_bs_dev *dev; 1327 struct spdk_io_channel *channel; 1328 1329 dev = init_dev(); 1330 1331 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1332 poll_threads(); 1333 CU_ASSERT(g_bserrno == 0); 1334 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1335 bs = g_bs; 1336 1337 channel = spdk_bs_alloc_io_channel(bs); 1338 CU_ASSERT(channel != NULL); 1339 1340 spdk_bs_free_io_channel(channel); 1341 poll_threads(); 1342 1343 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1344 poll_threads(); 1345 CU_ASSERT(g_bserrno == 0); 1346 g_bs = NULL; 1347 } 1348 1349 static void 1350 blob_write(void) 1351 { 1352 struct spdk_blob_store *bs; 1353 struct spdk_bs_dev *dev; 1354 struct spdk_blob *blob; 1355 struct spdk_io_channel *channel; 1356 spdk_blob_id blobid; 1357 uint64_t pages_per_cluster; 1358 uint8_t payload[10 * 4096]; 1359 1360 dev = init_dev(); 1361 1362 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1363 poll_threads(); 1364 CU_ASSERT(g_bserrno == 0); 1365 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1366 bs = g_bs; 1367 1368 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1369 1370 channel = spdk_bs_alloc_io_channel(bs); 1371 CU_ASSERT(channel != NULL); 1372 1373 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1374 poll_threads(); 1375 CU_ASSERT(g_bserrno == 0); 1376 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1377 blobid = g_blobid; 1378 1379 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1380 poll_threads(); 1381 CU_ASSERT(g_bserrno == 0); 1382 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1383 blob = g_blob; 1384 1385 /* Write to a blob with 0 size */ 1386 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1387 poll_threads(); 1388 CU_ASSERT(g_bserrno == -EINVAL); 1389 1390 /* Resize the blob */ 1391 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1392 poll_threads(); 1393 CU_ASSERT(g_bserrno == 0); 1394 1395 /* Confirm that write fails if blob is marked read-only. */ 1396 blob->data_ro = true; 1397 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1398 poll_threads(); 1399 CU_ASSERT(g_bserrno == -EPERM); 1400 blob->data_ro = false; 1401 1402 /* Write to the blob */ 1403 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1404 poll_threads(); 1405 CU_ASSERT(g_bserrno == 0); 1406 1407 /* Write starting beyond the end */ 1408 spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1409 NULL); 1410 poll_threads(); 1411 CU_ASSERT(g_bserrno == -EINVAL); 1412 1413 /* Write starting at a valid location but going off the end */ 1414 spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1415 blob_op_complete, NULL); 1416 poll_threads(); 1417 CU_ASSERT(g_bserrno == -EINVAL); 1418 1419 spdk_blob_close(blob, blob_op_complete, NULL); 1420 poll_threads(); 1421 CU_ASSERT(g_bserrno == 0); 1422 1423 spdk_bs_free_io_channel(channel); 1424 poll_threads(); 1425 1426 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1427 poll_threads(); 1428 CU_ASSERT(g_bserrno == 0); 1429 g_bs = NULL; 1430 } 1431 1432 static void 1433 blob_read(void) 1434 { 1435 struct spdk_blob_store *bs; 1436 struct spdk_bs_dev *dev; 1437 struct spdk_blob *blob; 1438 struct spdk_io_channel *channel; 1439 spdk_blob_id blobid; 1440 uint64_t pages_per_cluster; 1441 uint8_t payload[10 * 4096]; 1442 1443 dev = init_dev(); 1444 1445 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1446 poll_threads(); 1447 CU_ASSERT(g_bserrno == 0); 1448 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1449 bs = g_bs; 1450 1451 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1452 1453 channel = spdk_bs_alloc_io_channel(bs); 1454 CU_ASSERT(channel != NULL); 1455 1456 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1457 poll_threads(); 1458 CU_ASSERT(g_bserrno == 0); 1459 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1460 blobid = g_blobid; 1461 1462 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1463 poll_threads(); 1464 CU_ASSERT(g_bserrno == 0); 1465 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1466 blob = g_blob; 1467 1468 /* Read from a blob with 0 size */ 1469 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1470 poll_threads(); 1471 CU_ASSERT(g_bserrno == -EINVAL); 1472 1473 /* Resize the blob */ 1474 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1475 poll_threads(); 1476 CU_ASSERT(g_bserrno == 0); 1477 1478 /* Confirm that read passes if blob is marked read-only. */ 1479 blob->data_ro = true; 1480 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1481 poll_threads(); 1482 CU_ASSERT(g_bserrno == 0); 1483 blob->data_ro = false; 1484 1485 /* Read from the blob */ 1486 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1487 poll_threads(); 1488 CU_ASSERT(g_bserrno == 0); 1489 1490 /* Read starting beyond the end */ 1491 spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1492 NULL); 1493 poll_threads(); 1494 CU_ASSERT(g_bserrno == -EINVAL); 1495 1496 /* Read starting at a valid location but going off the end */ 1497 spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1498 blob_op_complete, NULL); 1499 poll_threads(); 1500 CU_ASSERT(g_bserrno == -EINVAL); 1501 1502 spdk_blob_close(blob, blob_op_complete, NULL); 1503 poll_threads(); 1504 CU_ASSERT(g_bserrno == 0); 1505 1506 spdk_bs_free_io_channel(channel); 1507 poll_threads(); 1508 1509 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1510 poll_threads(); 1511 CU_ASSERT(g_bserrno == 0); 1512 g_bs = NULL; 1513 } 1514 1515 static void 1516 blob_rw_verify(void) 1517 { 1518 struct spdk_blob_store *bs; 1519 struct spdk_bs_dev *dev; 1520 struct spdk_blob *blob; 1521 struct spdk_io_channel *channel; 1522 spdk_blob_id blobid; 1523 uint8_t payload_read[10 * 4096]; 1524 uint8_t payload_write[10 * 4096]; 1525 1526 dev = init_dev(); 1527 1528 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1529 poll_threads(); 1530 CU_ASSERT(g_bserrno == 0); 1531 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1532 bs = g_bs; 1533 1534 channel = spdk_bs_alloc_io_channel(bs); 1535 CU_ASSERT(channel != NULL); 1536 1537 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1538 poll_threads(); 1539 CU_ASSERT(g_bserrno == 0); 1540 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1541 blobid = g_blobid; 1542 1543 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1544 poll_threads(); 1545 CU_ASSERT(g_bserrno == 0); 1546 CU_ASSERT(g_blob != NULL); 1547 blob = g_blob; 1548 1549 spdk_blob_resize(blob, 32, blob_op_complete, NULL); 1550 poll_threads(); 1551 CU_ASSERT(g_bserrno == 0); 1552 1553 memset(payload_write, 0xE5, sizeof(payload_write)); 1554 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 1555 poll_threads(); 1556 CU_ASSERT(g_bserrno == 0); 1557 1558 memset(payload_read, 0x00, sizeof(payload_read)); 1559 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 1560 poll_threads(); 1561 CU_ASSERT(g_bserrno == 0); 1562 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 1563 1564 spdk_blob_close(blob, blob_op_complete, NULL); 1565 poll_threads(); 1566 CU_ASSERT(g_bserrno == 0); 1567 1568 spdk_bs_free_io_channel(channel); 1569 poll_threads(); 1570 1571 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1572 poll_threads(); 1573 CU_ASSERT(g_bserrno == 0); 1574 g_bs = NULL; 1575 } 1576 1577 static void 1578 blob_rw_verify_iov(void) 1579 { 1580 struct spdk_blob_store *bs; 1581 struct spdk_bs_dev *dev; 1582 struct spdk_blob *blob; 1583 struct spdk_io_channel *channel; 1584 spdk_blob_id blobid; 1585 uint8_t payload_read[10 * 4096]; 1586 uint8_t payload_write[10 * 4096]; 1587 struct iovec iov_read[3]; 1588 struct iovec iov_write[3]; 1589 void *buf; 1590 1591 dev = init_dev(); 1592 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1593 1594 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1595 poll_threads(); 1596 CU_ASSERT(g_bserrno == 0); 1597 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1598 bs = g_bs; 1599 1600 channel = spdk_bs_alloc_io_channel(bs); 1601 CU_ASSERT(channel != NULL); 1602 1603 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1604 poll_threads(); 1605 CU_ASSERT(g_bserrno == 0); 1606 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1607 blobid = g_blobid; 1608 1609 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1610 poll_threads(); 1611 CU_ASSERT(g_bserrno == 0); 1612 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1613 blob = g_blob; 1614 1615 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1616 poll_threads(); 1617 CU_ASSERT(g_bserrno == 0); 1618 1619 /* 1620 * Manually adjust the offset of the blob's second cluster. This allows 1621 * us to make sure that the readv/write code correctly accounts for I/O 1622 * that cross cluster boundaries. Start by asserting that the allocated 1623 * clusters are where we expect before modifying the second cluster. 1624 */ 1625 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 1626 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 1627 blob->active.clusters[1] = 3 * 256; 1628 1629 memset(payload_write, 0xE5, sizeof(payload_write)); 1630 iov_write[0].iov_base = payload_write; 1631 iov_write[0].iov_len = 1 * 4096; 1632 iov_write[1].iov_base = payload_write + 1 * 4096; 1633 iov_write[1].iov_len = 5 * 4096; 1634 iov_write[2].iov_base = payload_write + 6 * 4096; 1635 iov_write[2].iov_len = 4 * 4096; 1636 /* 1637 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1638 * will get written to the first cluster, the last 4 to the second cluster. 1639 */ 1640 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1641 poll_threads(); 1642 CU_ASSERT(g_bserrno == 0); 1643 1644 memset(payload_read, 0xAA, sizeof(payload_read)); 1645 iov_read[0].iov_base = payload_read; 1646 iov_read[0].iov_len = 3 * 4096; 1647 iov_read[1].iov_base = payload_read + 3 * 4096; 1648 iov_read[1].iov_len = 4 * 4096; 1649 iov_read[2].iov_base = payload_read + 7 * 4096; 1650 iov_read[2].iov_len = 3 * 4096; 1651 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 1652 poll_threads(); 1653 CU_ASSERT(g_bserrno == 0); 1654 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 1655 1656 buf = calloc(1, 256 * 4096); 1657 SPDK_CU_ASSERT_FATAL(buf != NULL); 1658 /* Check that cluster 2 on "disk" was not modified. */ 1659 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 1660 free(buf); 1661 1662 spdk_blob_close(blob, blob_op_complete, NULL); 1663 poll_threads(); 1664 CU_ASSERT(g_bserrno == 0); 1665 1666 spdk_bs_free_io_channel(channel); 1667 poll_threads(); 1668 1669 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1670 poll_threads(); 1671 CU_ASSERT(g_bserrno == 0); 1672 g_bs = NULL; 1673 } 1674 1675 static uint32_t 1676 bs_channel_get_req_count(struct spdk_io_channel *_channel) 1677 { 1678 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 1679 struct spdk_bs_request_set *set; 1680 uint32_t count = 0; 1681 1682 TAILQ_FOREACH(set, &channel->reqs, link) { 1683 count++; 1684 } 1685 1686 return count; 1687 } 1688 1689 static void 1690 blob_rw_verify_iov_nomem(void) 1691 { 1692 struct spdk_blob_store *bs; 1693 struct spdk_bs_dev *dev; 1694 struct spdk_blob *blob; 1695 struct spdk_io_channel *channel; 1696 spdk_blob_id blobid; 1697 uint8_t payload_write[10 * 4096]; 1698 struct iovec iov_write[3]; 1699 uint32_t req_count; 1700 1701 dev = init_dev(); 1702 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1703 1704 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1705 poll_threads(); 1706 CU_ASSERT(g_bserrno == 0); 1707 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1708 bs = g_bs; 1709 1710 channel = spdk_bs_alloc_io_channel(bs); 1711 CU_ASSERT(channel != NULL); 1712 1713 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1714 poll_threads(); 1715 CU_ASSERT(g_bserrno == 0); 1716 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1717 blobid = g_blobid; 1718 1719 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1720 poll_threads(); 1721 CU_ASSERT(g_bserrno == 0); 1722 CU_ASSERT(g_blob != NULL); 1723 blob = g_blob; 1724 1725 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1726 poll_threads(); 1727 CU_ASSERT(g_bserrno == 0); 1728 1729 /* 1730 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1731 * will get written to the first cluster, the last 4 to the second cluster. 1732 */ 1733 iov_write[0].iov_base = payload_write; 1734 iov_write[0].iov_len = 1 * 4096; 1735 iov_write[1].iov_base = payload_write + 1 * 4096; 1736 iov_write[1].iov_len = 5 * 4096; 1737 iov_write[2].iov_base = payload_write + 6 * 4096; 1738 iov_write[2].iov_len = 4 * 4096; 1739 MOCK_SET(calloc, NULL); 1740 req_count = bs_channel_get_req_count(channel); 1741 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1742 poll_threads(); 1743 CU_ASSERT(g_bserrno = -ENOMEM); 1744 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 1745 MOCK_CLEAR(calloc); 1746 1747 spdk_blob_close(blob, blob_op_complete, NULL); 1748 poll_threads(); 1749 CU_ASSERT(g_bserrno == 0); 1750 1751 spdk_bs_free_io_channel(channel); 1752 poll_threads(); 1753 1754 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1755 poll_threads(); 1756 CU_ASSERT(g_bserrno == 0); 1757 g_bs = NULL; 1758 } 1759 1760 static void 1761 blob_rw_iov_read_only(void) 1762 { 1763 struct spdk_blob_store *bs; 1764 struct spdk_bs_dev *dev; 1765 struct spdk_blob *blob; 1766 struct spdk_io_channel *channel; 1767 spdk_blob_id blobid; 1768 uint8_t payload_read[4096]; 1769 uint8_t payload_write[4096]; 1770 struct iovec iov_read; 1771 struct iovec iov_write; 1772 1773 dev = init_dev(); 1774 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1775 1776 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1777 poll_threads(); 1778 CU_ASSERT(g_bserrno == 0); 1779 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1780 bs = g_bs; 1781 1782 channel = spdk_bs_alloc_io_channel(bs); 1783 CU_ASSERT(channel != NULL); 1784 1785 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1786 poll_threads(); 1787 CU_ASSERT(g_bserrno == 0); 1788 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1789 blobid = g_blobid; 1790 1791 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1792 poll_threads(); 1793 CU_ASSERT(g_bserrno == 0); 1794 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1795 blob = g_blob; 1796 1797 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1798 poll_threads(); 1799 CU_ASSERT(g_bserrno == 0); 1800 1801 /* Verify that writev failed if read_only flag is set. */ 1802 blob->data_ro = true; 1803 iov_write.iov_base = payload_write; 1804 iov_write.iov_len = sizeof(payload_write); 1805 spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL); 1806 poll_threads(); 1807 CU_ASSERT(g_bserrno == -EPERM); 1808 1809 /* Verify that reads pass if data_ro flag is set. */ 1810 iov_read.iov_base = payload_read; 1811 iov_read.iov_len = sizeof(payload_read); 1812 spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL); 1813 poll_threads(); 1814 CU_ASSERT(g_bserrno == 0); 1815 1816 spdk_blob_close(blob, blob_op_complete, NULL); 1817 poll_threads(); 1818 CU_ASSERT(g_bserrno == 0); 1819 1820 spdk_bs_free_io_channel(channel); 1821 poll_threads(); 1822 1823 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1824 poll_threads(); 1825 CU_ASSERT(g_bserrno == 0); 1826 g_bs = NULL; 1827 } 1828 1829 static void 1830 _blob_io_read_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel, 1831 uint8_t *payload, uint64_t offset, uint64_t length, 1832 spdk_blob_op_complete cb_fn, void *cb_arg) 1833 { 1834 uint64_t i; 1835 uint8_t *buf; 1836 uint64_t page_size = spdk_bs_get_page_size(blob->bs); 1837 1838 /* To be sure that operation is NOT splitted, read one page at the time */ 1839 buf = payload; 1840 for (i = 0; i < length; i++) { 1841 spdk_blob_io_read(blob, channel, buf, i + offset, 1, blob_op_complete, NULL); 1842 poll_threads(); 1843 if (g_bserrno != 0) { 1844 /* Pass the error code up */ 1845 break; 1846 } 1847 buf += page_size; 1848 } 1849 1850 cb_fn(cb_arg, g_bserrno); 1851 } 1852 1853 static void 1854 _blob_io_write_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel, 1855 uint8_t *payload, uint64_t offset, uint64_t length, 1856 spdk_blob_op_complete cb_fn, void *cb_arg) 1857 { 1858 uint64_t i; 1859 uint8_t *buf; 1860 uint64_t page_size = spdk_bs_get_page_size(blob->bs); 1861 1862 /* To be sure that operation is NOT splitted, write one page at the time */ 1863 buf = payload; 1864 for (i = 0; i < length; i++) { 1865 spdk_blob_io_write(blob, channel, buf, i + offset, 1, blob_op_complete, NULL); 1866 poll_threads(); 1867 if (g_bserrno != 0) { 1868 /* Pass the error code up */ 1869 break; 1870 } 1871 buf += page_size; 1872 } 1873 1874 cb_fn(cb_arg, g_bserrno); 1875 } 1876 1877 static void 1878 blob_operation_split_rw(void) 1879 { 1880 struct spdk_blob_store *bs; 1881 struct spdk_bs_dev *dev; 1882 struct spdk_blob *blob; 1883 struct spdk_io_channel *channel; 1884 struct spdk_blob_opts opts; 1885 spdk_blob_id blobid; 1886 uint64_t cluster_size; 1887 1888 uint64_t payload_size; 1889 uint8_t *payload_read; 1890 uint8_t *payload_write; 1891 uint8_t *payload_pattern; 1892 1893 uint64_t page_size; 1894 uint64_t pages_per_cluster; 1895 uint64_t pages_per_payload; 1896 1897 uint64_t i; 1898 1899 dev = init_dev(); 1900 1901 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1902 poll_threads(); 1903 CU_ASSERT(g_bserrno == 0); 1904 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1905 bs = g_bs; 1906 1907 cluster_size = spdk_bs_get_cluster_size(bs); 1908 page_size = spdk_bs_get_page_size(bs); 1909 pages_per_cluster = cluster_size / page_size; 1910 pages_per_payload = pages_per_cluster * 5; 1911 payload_size = cluster_size * 5; 1912 1913 payload_read = malloc(payload_size); 1914 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 1915 1916 payload_write = malloc(payload_size); 1917 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 1918 1919 payload_pattern = malloc(payload_size); 1920 SPDK_CU_ASSERT_FATAL(payload_pattern != NULL); 1921 1922 /* Prepare random pattern to write */ 1923 memset(payload_pattern, 0xFF, payload_size); 1924 for (i = 0; i < pages_per_payload; i++) { 1925 *((uint64_t *)(payload_pattern + page_size * i)) = (i + 1); 1926 } 1927 1928 channel = spdk_bs_alloc_io_channel(bs); 1929 SPDK_CU_ASSERT_FATAL(channel != NULL); 1930 1931 /* Create blob */ 1932 spdk_blob_opts_init(&opts); 1933 opts.thin_provision = false; 1934 opts.num_clusters = 5; 1935 1936 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1937 poll_threads(); 1938 CU_ASSERT(g_bserrno == 0); 1939 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1940 blobid = g_blobid; 1941 1942 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1943 poll_threads(); 1944 CU_ASSERT(g_bserrno == 0); 1945 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1946 blob = g_blob; 1947 1948 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 1949 1950 /* Initial read should return zeroed payload */ 1951 memset(payload_read, 0xFF, payload_size); 1952 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1953 poll_threads(); 1954 CU_ASSERT(g_bserrno == 0); 1955 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 1956 1957 /* Fill whole blob except last page */ 1958 spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload - 1, 1959 blob_op_complete, NULL); 1960 poll_threads(); 1961 CU_ASSERT(g_bserrno == 0); 1962 1963 /* Write last page with a pattern */ 1964 spdk_blob_io_write(blob, channel, payload_pattern, pages_per_payload - 1, 1, 1965 blob_op_complete, NULL); 1966 poll_threads(); 1967 CU_ASSERT(g_bserrno == 0); 1968 1969 /* Read whole blob and check consistency */ 1970 memset(payload_read, 0xFF, payload_size); 1971 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1972 poll_threads(); 1973 CU_ASSERT(g_bserrno == 0); 1974 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0); 1975 CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0); 1976 1977 /* Fill whole blob except first page */ 1978 spdk_blob_io_write(blob, channel, payload_pattern, 1, pages_per_payload - 1, 1979 blob_op_complete, NULL); 1980 poll_threads(); 1981 CU_ASSERT(g_bserrno == 0); 1982 1983 /* Write first page with a pattern */ 1984 spdk_blob_io_write(blob, channel, payload_pattern, 0, 1, 1985 blob_op_complete, NULL); 1986 poll_threads(); 1987 CU_ASSERT(g_bserrno == 0); 1988 1989 /* Read whole blob and check consistency */ 1990 memset(payload_read, 0xFF, payload_size); 1991 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1992 poll_threads(); 1993 CU_ASSERT(g_bserrno == 0); 1994 CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0); 1995 CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0); 1996 1997 1998 /* Fill whole blob with a pattern (5 clusters) */ 1999 2000 /* 1. Read test. */ 2001 _blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload, 2002 blob_op_complete, NULL); 2003 poll_threads(); 2004 CU_ASSERT(g_bserrno == 0); 2005 2006 memset(payload_read, 0xFF, payload_size); 2007 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 2008 poll_threads(); 2009 poll_threads(); 2010 CU_ASSERT(g_bserrno == 0); 2011 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 2012 2013 /* 2. Write test. */ 2014 spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload, 2015 blob_op_complete, NULL); 2016 poll_threads(); 2017 CU_ASSERT(g_bserrno == 0); 2018 2019 memset(payload_read, 0xFF, payload_size); 2020 _blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 2021 poll_threads(); 2022 CU_ASSERT(g_bserrno == 0); 2023 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 2024 2025 spdk_blob_close(blob, blob_op_complete, NULL); 2026 poll_threads(); 2027 CU_ASSERT(g_bserrno == 0); 2028 2029 spdk_bs_free_io_channel(channel); 2030 poll_threads(); 2031 2032 /* Unload the blob store */ 2033 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2034 poll_threads(); 2035 CU_ASSERT(g_bserrno == 0); 2036 g_bs = NULL; 2037 g_blob = NULL; 2038 g_blobid = 0; 2039 2040 free(payload_read); 2041 free(payload_write); 2042 free(payload_pattern); 2043 } 2044 2045 static void 2046 blob_operation_split_rw_iov(void) 2047 { 2048 struct spdk_blob_store *bs; 2049 struct spdk_bs_dev *dev; 2050 struct spdk_blob *blob; 2051 struct spdk_io_channel *channel; 2052 struct spdk_blob_opts opts; 2053 spdk_blob_id blobid; 2054 uint64_t cluster_size; 2055 2056 uint64_t payload_size; 2057 uint8_t *payload_read; 2058 uint8_t *payload_write; 2059 uint8_t *payload_pattern; 2060 2061 uint64_t page_size; 2062 uint64_t pages_per_cluster; 2063 uint64_t pages_per_payload; 2064 2065 struct iovec iov_read[2]; 2066 struct iovec iov_write[2]; 2067 2068 uint64_t i, j; 2069 2070 dev = init_dev(); 2071 2072 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2073 poll_threads(); 2074 CU_ASSERT(g_bserrno == 0); 2075 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2076 bs = g_bs; 2077 2078 cluster_size = spdk_bs_get_cluster_size(bs); 2079 page_size = spdk_bs_get_page_size(bs); 2080 pages_per_cluster = cluster_size / page_size; 2081 pages_per_payload = pages_per_cluster * 5; 2082 payload_size = cluster_size * 5; 2083 2084 payload_read = malloc(payload_size); 2085 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 2086 2087 payload_write = malloc(payload_size); 2088 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 2089 2090 payload_pattern = malloc(payload_size); 2091 SPDK_CU_ASSERT_FATAL(payload_pattern != NULL); 2092 2093 /* Prepare random pattern to write */ 2094 for (i = 0; i < pages_per_payload; i++) { 2095 for (j = 0; j < page_size / sizeof(uint64_t); j++) { 2096 uint64_t *tmp; 2097 2098 tmp = (uint64_t *)payload_pattern; 2099 tmp += ((page_size * i) / sizeof(uint64_t)) + j; 2100 *tmp = i + 1; 2101 } 2102 } 2103 2104 channel = spdk_bs_alloc_io_channel(bs); 2105 SPDK_CU_ASSERT_FATAL(channel != NULL); 2106 2107 /* Create blob */ 2108 spdk_blob_opts_init(&opts); 2109 opts.thin_provision = false; 2110 opts.num_clusters = 5; 2111 2112 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2113 poll_threads(); 2114 CU_ASSERT(g_bserrno == 0); 2115 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2116 blobid = g_blobid; 2117 2118 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2119 poll_threads(); 2120 CU_ASSERT(g_bserrno == 0); 2121 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2122 blob = g_blob; 2123 2124 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 2125 2126 /* Initial read should return zeroes payload */ 2127 memset(payload_read, 0xFF, payload_size); 2128 iov_read[0].iov_base = payload_read; 2129 iov_read[0].iov_len = cluster_size * 3; 2130 iov_read[1].iov_base = payload_read + cluster_size * 3; 2131 iov_read[1].iov_len = cluster_size * 2; 2132 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 2133 poll_threads(); 2134 CU_ASSERT(g_bserrno == 0); 2135 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 2136 2137 /* First of iovs fills whole blob except last page and second of iovs writes last page 2138 * with a pattern. */ 2139 iov_write[0].iov_base = payload_pattern; 2140 iov_write[0].iov_len = payload_size - page_size; 2141 iov_write[1].iov_base = payload_pattern; 2142 iov_write[1].iov_len = page_size; 2143 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 2144 poll_threads(); 2145 CU_ASSERT(g_bserrno == 0); 2146 2147 /* Read whole blob and check consistency */ 2148 memset(payload_read, 0xFF, payload_size); 2149 iov_read[0].iov_base = payload_read; 2150 iov_read[0].iov_len = cluster_size * 2; 2151 iov_read[1].iov_base = payload_read + cluster_size * 2; 2152 iov_read[1].iov_len = cluster_size * 3; 2153 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 2154 poll_threads(); 2155 CU_ASSERT(g_bserrno == 0); 2156 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0); 2157 CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0); 2158 2159 /* First of iovs fills only first page and second of iovs writes whole blob except 2160 * first page with a pattern. */ 2161 iov_write[0].iov_base = payload_pattern; 2162 iov_write[0].iov_len = page_size; 2163 iov_write[1].iov_base = payload_pattern; 2164 iov_write[1].iov_len = payload_size - page_size; 2165 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 2166 poll_threads(); 2167 CU_ASSERT(g_bserrno == 0); 2168 2169 /* Read whole blob and check consistency */ 2170 memset(payload_read, 0xFF, payload_size); 2171 iov_read[0].iov_base = payload_read; 2172 iov_read[0].iov_len = cluster_size * 4; 2173 iov_read[1].iov_base = payload_read + cluster_size * 4; 2174 iov_read[1].iov_len = cluster_size; 2175 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 2176 poll_threads(); 2177 CU_ASSERT(g_bserrno == 0); 2178 CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0); 2179 CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0); 2180 2181 2182 /* Fill whole blob with a pattern (5 clusters) */ 2183 2184 /* 1. Read test. */ 2185 _blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload, 2186 blob_op_complete, NULL); 2187 poll_threads(); 2188 CU_ASSERT(g_bserrno == 0); 2189 2190 memset(payload_read, 0xFF, payload_size); 2191 iov_read[0].iov_base = payload_read; 2192 iov_read[0].iov_len = cluster_size; 2193 iov_read[1].iov_base = payload_read + cluster_size; 2194 iov_read[1].iov_len = cluster_size * 4; 2195 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 2196 poll_threads(); 2197 CU_ASSERT(g_bserrno == 0); 2198 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 2199 2200 /* 2. Write test. */ 2201 iov_write[0].iov_base = payload_read; 2202 iov_write[0].iov_len = cluster_size * 2; 2203 iov_write[1].iov_base = payload_read + cluster_size * 2; 2204 iov_write[1].iov_len = cluster_size * 3; 2205 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 2206 poll_threads(); 2207 CU_ASSERT(g_bserrno == 0); 2208 2209 memset(payload_read, 0xFF, payload_size); 2210 _blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 2211 poll_threads(); 2212 CU_ASSERT(g_bserrno == 0); 2213 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 2214 2215 spdk_blob_close(blob, blob_op_complete, NULL); 2216 CU_ASSERT(g_bserrno == 0); 2217 2218 spdk_bs_free_io_channel(channel); 2219 poll_threads(); 2220 2221 /* Unload the blob store */ 2222 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2223 poll_threads(); 2224 CU_ASSERT(g_bserrno == 0); 2225 g_bs = NULL; 2226 g_blob = NULL; 2227 g_blobid = 0; 2228 2229 free(payload_read); 2230 free(payload_write); 2231 free(payload_pattern); 2232 } 2233 2234 static void 2235 blob_unmap(void) 2236 { 2237 struct spdk_blob_store *bs; 2238 struct spdk_bs_dev *dev; 2239 struct spdk_blob *blob; 2240 struct spdk_io_channel *channel; 2241 spdk_blob_id blobid; 2242 struct spdk_blob_opts opts; 2243 uint8_t payload[4096]; 2244 int i; 2245 2246 dev = init_dev(); 2247 2248 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2249 poll_threads(); 2250 CU_ASSERT(g_bserrno == 0); 2251 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2252 bs = g_bs; 2253 2254 channel = spdk_bs_alloc_io_channel(bs); 2255 CU_ASSERT(channel != NULL); 2256 2257 spdk_blob_opts_init(&opts); 2258 opts.num_clusters = 10; 2259 2260 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2261 poll_threads(); 2262 CU_ASSERT(g_bserrno == 0); 2263 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2264 blobid = g_blobid; 2265 2266 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2267 poll_threads(); 2268 CU_ASSERT(g_bserrno == 0); 2269 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2270 blob = g_blob; 2271 2272 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2273 poll_threads(); 2274 CU_ASSERT(g_bserrno == 0); 2275 2276 memset(payload, 0, sizeof(payload)); 2277 payload[0] = 0xFF; 2278 2279 /* 2280 * Set first byte of every cluster to 0xFF. 2281 * First cluster on device is reserved so let's start from cluster number 1 2282 */ 2283 for (i = 1; i < 11; i++) { 2284 g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF; 2285 } 2286 2287 /* Confirm writes */ 2288 for (i = 0; i < 10; i++) { 2289 payload[0] = 0; 2290 spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1, 2291 blob_op_complete, NULL); 2292 poll_threads(); 2293 CU_ASSERT(g_bserrno == 0); 2294 CU_ASSERT(payload[0] == 0xFF); 2295 } 2296 2297 /* Mark some clusters as unallocated */ 2298 blob->active.clusters[1] = 0; 2299 blob->active.clusters[2] = 0; 2300 blob->active.clusters[3] = 0; 2301 blob->active.clusters[6] = 0; 2302 blob->active.clusters[8] = 0; 2303 2304 /* Unmap clusters by resizing to 0 */ 2305 spdk_blob_resize(blob, 0, blob_op_complete, NULL); 2306 poll_threads(); 2307 CU_ASSERT(g_bserrno == 0); 2308 2309 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2310 poll_threads(); 2311 CU_ASSERT(g_bserrno == 0); 2312 2313 /* Confirm that only 'allocated' clusters were unmapped */ 2314 for (i = 1; i < 11; i++) { 2315 switch (i) { 2316 case 2: 2317 case 3: 2318 case 4: 2319 case 7: 2320 case 9: 2321 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF); 2322 break; 2323 default: 2324 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0); 2325 break; 2326 } 2327 } 2328 2329 spdk_blob_close(blob, blob_op_complete, NULL); 2330 poll_threads(); 2331 CU_ASSERT(g_bserrno == 0); 2332 2333 spdk_bs_free_io_channel(channel); 2334 poll_threads(); 2335 2336 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2337 poll_threads(); 2338 CU_ASSERT(g_bserrno == 0); 2339 g_bs = NULL; 2340 } 2341 2342 2343 static void 2344 blob_iter(void) 2345 { 2346 struct spdk_blob_store *bs; 2347 struct spdk_bs_dev *dev; 2348 struct spdk_blob *blob; 2349 spdk_blob_id blobid; 2350 2351 dev = init_dev(); 2352 2353 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2354 poll_threads(); 2355 CU_ASSERT(g_bserrno == 0); 2356 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2357 bs = g_bs; 2358 2359 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 2360 poll_threads(); 2361 CU_ASSERT(g_blob == NULL); 2362 CU_ASSERT(g_bserrno == -ENOENT); 2363 2364 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2365 poll_threads(); 2366 CU_ASSERT(g_bserrno == 0); 2367 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2368 blobid = g_blobid; 2369 2370 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 2371 poll_threads(); 2372 CU_ASSERT(g_blob != NULL); 2373 CU_ASSERT(g_bserrno == 0); 2374 blob = g_blob; 2375 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 2376 2377 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 2378 poll_threads(); 2379 CU_ASSERT(g_blob == NULL); 2380 CU_ASSERT(g_bserrno == -ENOENT); 2381 2382 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2383 poll_threads(); 2384 CU_ASSERT(g_bserrno == 0); 2385 g_bs = NULL; 2386 } 2387 2388 static void 2389 blob_xattr(void) 2390 { 2391 struct spdk_blob_store *bs; 2392 struct spdk_bs_dev *dev; 2393 struct spdk_blob *blob; 2394 spdk_blob_id blobid; 2395 uint64_t length; 2396 int rc; 2397 const char *name1, *name2; 2398 const void *value; 2399 size_t value_len; 2400 struct spdk_xattr_names *names; 2401 2402 dev = init_dev(); 2403 2404 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2405 poll_threads(); 2406 CU_ASSERT(g_bserrno == 0); 2407 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2408 bs = g_bs; 2409 2410 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2411 poll_threads(); 2412 CU_ASSERT(g_bserrno == 0); 2413 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2414 blobid = g_blobid; 2415 2416 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2417 poll_threads(); 2418 CU_ASSERT(g_bserrno == 0); 2419 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2420 blob = g_blob; 2421 2422 /* Test that set_xattr fails if md_ro flag is set. */ 2423 blob->md_ro = true; 2424 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2425 CU_ASSERT(rc == -EPERM); 2426 2427 blob->md_ro = false; 2428 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2429 CU_ASSERT(rc == 0); 2430 2431 length = 2345; 2432 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2433 CU_ASSERT(rc == 0); 2434 2435 /* Overwrite "length" xattr. */ 2436 length = 3456; 2437 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2438 CU_ASSERT(rc == 0); 2439 2440 /* get_xattr should still work even if md_ro flag is set. */ 2441 value = NULL; 2442 blob->md_ro = true; 2443 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2444 CU_ASSERT(rc == 0); 2445 SPDK_CU_ASSERT_FATAL(value != NULL); 2446 CU_ASSERT(*(uint64_t *)value == length); 2447 CU_ASSERT(value_len == 8); 2448 blob->md_ro = false; 2449 2450 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2451 CU_ASSERT(rc == -ENOENT); 2452 2453 names = NULL; 2454 rc = spdk_blob_get_xattr_names(blob, &names); 2455 CU_ASSERT(rc == 0); 2456 SPDK_CU_ASSERT_FATAL(names != NULL); 2457 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 2458 name1 = spdk_xattr_names_get_name(names, 0); 2459 SPDK_CU_ASSERT_FATAL(name1 != NULL); 2460 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 2461 name2 = spdk_xattr_names_get_name(names, 1); 2462 SPDK_CU_ASSERT_FATAL(name2 != NULL); 2463 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 2464 CU_ASSERT(strcmp(name1, name2)); 2465 spdk_xattr_names_free(names); 2466 2467 /* Confirm that remove_xattr fails if md_ro is set to true. */ 2468 blob->md_ro = true; 2469 rc = spdk_blob_remove_xattr(blob, "name"); 2470 CU_ASSERT(rc == -EPERM); 2471 2472 blob->md_ro = false; 2473 rc = spdk_blob_remove_xattr(blob, "name"); 2474 CU_ASSERT(rc == 0); 2475 2476 rc = spdk_blob_remove_xattr(blob, "foobar"); 2477 CU_ASSERT(rc == -ENOENT); 2478 2479 /* Set internal xattr */ 2480 length = 7898; 2481 rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true); 2482 CU_ASSERT(rc == 0); 2483 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 2484 CU_ASSERT(rc == 0); 2485 CU_ASSERT(*(uint64_t *)value == length); 2486 /* try to get public xattr with same name */ 2487 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 2488 CU_ASSERT(rc != 0); 2489 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false); 2490 CU_ASSERT(rc != 0); 2491 /* Check if SPDK_BLOB_INTERNAL_XATTR is set */ 2492 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 2493 SPDK_BLOB_INTERNAL_XATTR) 2494 2495 spdk_blob_close(blob, blob_op_complete, NULL); 2496 poll_threads(); 2497 2498 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2499 poll_threads(); 2500 2501 /* Check if xattrs are persisted */ 2502 dev = init_dev(); 2503 2504 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2505 poll_threads(); 2506 CU_ASSERT(g_bserrno == 0); 2507 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2508 2509 bs = g_bs; 2510 2511 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2512 poll_threads(); 2513 CU_ASSERT(g_bserrno == 0); 2514 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2515 blob = g_blob; 2516 2517 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 2518 CU_ASSERT(rc == 0); 2519 CU_ASSERT(*(uint64_t *)value == length); 2520 2521 /* try to get internal xattr trough public call */ 2522 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 2523 CU_ASSERT(rc != 0); 2524 2525 rc = _spdk_blob_remove_xattr(blob, "internal", true); 2526 CU_ASSERT(rc == 0); 2527 2528 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0); 2529 2530 CU_ASSERT(g_bserrno == 0); 2531 g_bs = NULL; 2532 } 2533 2534 static void 2535 bs_load(void) 2536 { 2537 struct spdk_bs_dev *dev; 2538 spdk_blob_id blobid; 2539 struct spdk_blob *blob; 2540 struct spdk_bs_super_block *super_block; 2541 uint64_t length; 2542 int rc; 2543 const void *value; 2544 size_t value_len; 2545 struct spdk_bs_opts opts; 2546 2547 dev = init_dev(); 2548 spdk_bs_opts_init(&opts); 2549 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2550 2551 /* Initialize a new blob store */ 2552 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2553 poll_threads(); 2554 CU_ASSERT(g_bserrno == 0); 2555 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2556 2557 /* Try to open a blobid that does not exist */ 2558 spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 2559 poll_threads(); 2560 CU_ASSERT(g_bserrno == -ENOENT); 2561 CU_ASSERT(g_blob == NULL); 2562 2563 /* Create a blob */ 2564 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2565 poll_threads(); 2566 CU_ASSERT(g_bserrno == 0); 2567 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2568 blobid = g_blobid; 2569 2570 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2571 poll_threads(); 2572 CU_ASSERT(g_bserrno == 0); 2573 CU_ASSERT(g_blob != NULL); 2574 blob = g_blob; 2575 2576 /* Try again to open valid blob but without the upper bit set */ 2577 spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 2578 poll_threads(); 2579 CU_ASSERT(g_bserrno == -ENOENT); 2580 CU_ASSERT(g_blob == NULL); 2581 2582 /* Set some xattrs */ 2583 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2584 CU_ASSERT(rc == 0); 2585 2586 length = 2345; 2587 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2588 CU_ASSERT(rc == 0); 2589 2590 /* Resize the blob */ 2591 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2592 poll_threads(); 2593 CU_ASSERT(g_bserrno == 0); 2594 2595 spdk_blob_close(blob, blob_op_complete, NULL); 2596 poll_threads(); 2597 CU_ASSERT(g_bserrno == 0); 2598 blob = NULL; 2599 g_blob = NULL; 2600 g_blobid = SPDK_BLOBID_INVALID; 2601 2602 /* Unload the blob store */ 2603 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2604 poll_threads(); 2605 CU_ASSERT(g_bserrno == 0); 2606 g_bs = NULL; 2607 g_blob = NULL; 2608 g_blobid = 0; 2609 2610 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2611 CU_ASSERT(super_block->clean == 1); 2612 2613 /* Load should fail for device with an unsupported blocklen */ 2614 dev = init_dev(); 2615 dev->blocklen = SPDK_BS_PAGE_SIZE * 2; 2616 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2617 poll_threads(); 2618 CU_ASSERT(g_bserrno == -EINVAL); 2619 2620 /* Load should when max_md_ops is set to zero */ 2621 dev = init_dev(); 2622 spdk_bs_opts_init(&opts); 2623 opts.max_md_ops = 0; 2624 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2625 poll_threads(); 2626 CU_ASSERT(g_bserrno == -EINVAL); 2627 2628 /* Load should when max_channel_ops is set to zero */ 2629 dev = init_dev(); 2630 spdk_bs_opts_init(&opts); 2631 opts.max_channel_ops = 0; 2632 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2633 poll_threads(); 2634 CU_ASSERT(g_bserrno == -EINVAL); 2635 2636 /* Load an existing blob store */ 2637 dev = init_dev(); 2638 spdk_bs_opts_init(&opts); 2639 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2640 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2641 poll_threads(); 2642 CU_ASSERT(g_bserrno == 0); 2643 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2644 2645 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2646 CU_ASSERT(super_block->clean == 1); 2647 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2648 2649 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2650 poll_threads(); 2651 CU_ASSERT(g_bserrno == 0); 2652 CU_ASSERT(g_blob != NULL); 2653 blob = g_blob; 2654 2655 /* Verify that blobstore is marked dirty after first metadata sync */ 2656 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2657 CU_ASSERT(super_block->clean == 1); 2658 2659 /* Get the xattrs */ 2660 value = NULL; 2661 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2662 CU_ASSERT(rc == 0); 2663 SPDK_CU_ASSERT_FATAL(value != NULL); 2664 CU_ASSERT(*(uint64_t *)value == length); 2665 CU_ASSERT(value_len == 8); 2666 2667 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2668 CU_ASSERT(rc == -ENOENT); 2669 2670 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2671 2672 spdk_blob_close(blob, blob_op_complete, NULL); 2673 poll_threads(); 2674 CU_ASSERT(g_bserrno == 0); 2675 blob = NULL; 2676 g_blob = NULL; 2677 2678 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2679 poll_threads(); 2680 CU_ASSERT(g_bserrno == 0); 2681 g_bs = NULL; 2682 2683 /* Load should fail: bdev size < saved size */ 2684 dev = init_dev(); 2685 dev->blockcnt /= 2; 2686 2687 spdk_bs_opts_init(&opts); 2688 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2689 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2690 poll_threads(); 2691 2692 CU_ASSERT(g_bserrno == -EILSEQ); 2693 2694 /* Load should succeed: bdev size > saved size */ 2695 dev = init_dev(); 2696 dev->blockcnt *= 4; 2697 2698 spdk_bs_opts_init(&opts); 2699 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2700 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2701 poll_threads(); 2702 2703 CU_ASSERT(g_bserrno == 0); 2704 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2705 poll_threads(); 2706 2707 2708 /* Test compatibility mode */ 2709 2710 dev = init_dev(); 2711 super_block->size = 0; 2712 super_block->crc = _spdk_blob_md_page_calc_crc(super_block); 2713 2714 spdk_bs_opts_init(&opts); 2715 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2716 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2717 poll_threads(); 2718 CU_ASSERT(g_bserrno == 0); 2719 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2720 2721 /* Create a blob */ 2722 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2723 poll_threads(); 2724 CU_ASSERT(g_bserrno == 0); 2725 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2726 2727 /* Blobstore should update number of blocks in super_block */ 2728 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2729 CU_ASSERT(super_block->clean == 0); 2730 2731 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2732 poll_threads(); 2733 CU_ASSERT(g_bserrno == 0); 2734 CU_ASSERT(super_block->clean == 1); 2735 g_bs = NULL; 2736 2737 } 2738 2739 static void 2740 bs_load_custom_cluster_size(void) 2741 { 2742 struct spdk_bs_dev *dev; 2743 struct spdk_bs_super_block *super_block; 2744 struct spdk_bs_opts opts; 2745 uint32_t custom_cluster_size = 4194304; /* 4MiB */ 2746 uint32_t cluster_sz; 2747 uint64_t total_clusters; 2748 2749 dev = init_dev(); 2750 spdk_bs_opts_init(&opts); 2751 opts.cluster_sz = custom_cluster_size; 2752 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2753 2754 /* Initialize a new blob store */ 2755 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2756 poll_threads(); 2757 CU_ASSERT(g_bserrno == 0); 2758 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2759 cluster_sz = g_bs->cluster_sz; 2760 total_clusters = g_bs->total_clusters; 2761 2762 /* Unload the blob store */ 2763 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2764 poll_threads(); 2765 CU_ASSERT(g_bserrno == 0); 2766 g_bs = NULL; 2767 g_blob = NULL; 2768 g_blobid = 0; 2769 2770 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2771 CU_ASSERT(super_block->clean == 1); 2772 2773 /* Load an existing blob store */ 2774 dev = init_dev(); 2775 spdk_bs_opts_init(&opts); 2776 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2777 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2778 poll_threads(); 2779 CU_ASSERT(g_bserrno == 0); 2780 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2781 /* Compare cluster size and number to one after initialization */ 2782 CU_ASSERT(cluster_sz == g_bs->cluster_sz); 2783 CU_ASSERT(total_clusters == g_bs->total_clusters); 2784 2785 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2786 CU_ASSERT(super_block->clean == 1); 2787 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2788 2789 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2790 poll_threads(); 2791 CU_ASSERT(g_bserrno == 0); 2792 CU_ASSERT(super_block->clean == 1); 2793 g_bs = NULL; 2794 } 2795 2796 static void 2797 bs_type(void) 2798 { 2799 struct spdk_bs_dev *dev; 2800 struct spdk_bs_opts opts; 2801 2802 dev = init_dev(); 2803 spdk_bs_opts_init(&opts); 2804 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2805 2806 /* Initialize a new blob store */ 2807 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2808 poll_threads(); 2809 CU_ASSERT(g_bserrno == 0); 2810 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2811 2812 /* Unload the blob store */ 2813 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2814 poll_threads(); 2815 CU_ASSERT(g_bserrno == 0); 2816 g_bs = NULL; 2817 g_blob = NULL; 2818 g_blobid = 0; 2819 2820 /* Load non existing blobstore type */ 2821 dev = init_dev(); 2822 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 2823 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2824 poll_threads(); 2825 CU_ASSERT(g_bserrno != 0); 2826 2827 /* Load with empty blobstore type */ 2828 dev = init_dev(); 2829 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2830 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2831 poll_threads(); 2832 CU_ASSERT(g_bserrno == 0); 2833 2834 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2835 poll_threads(); 2836 CU_ASSERT(g_bserrno == 0); 2837 g_bs = NULL; 2838 2839 /* Initialize a new blob store with empty bstype */ 2840 dev = init_dev(); 2841 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2842 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2843 poll_threads(); 2844 CU_ASSERT(g_bserrno == 0); 2845 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2846 2847 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2848 poll_threads(); 2849 CU_ASSERT(g_bserrno == 0); 2850 g_bs = NULL; 2851 2852 /* Load non existing blobstore type */ 2853 dev = init_dev(); 2854 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 2855 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2856 poll_threads(); 2857 CU_ASSERT(g_bserrno != 0); 2858 2859 /* Load with empty blobstore type */ 2860 dev = init_dev(); 2861 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2862 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2863 poll_threads(); 2864 CU_ASSERT(g_bserrno == 0); 2865 2866 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2867 poll_threads(); 2868 CU_ASSERT(g_bserrno == 0); 2869 g_bs = NULL; 2870 } 2871 2872 static void 2873 bs_super_block(void) 2874 { 2875 struct spdk_bs_dev *dev; 2876 struct spdk_bs_super_block *super_block; 2877 struct spdk_bs_opts opts; 2878 struct spdk_bs_super_block_ver1 super_block_v1; 2879 2880 dev = init_dev(); 2881 spdk_bs_opts_init(&opts); 2882 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2883 2884 /* Initialize a new blob store */ 2885 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2886 poll_threads(); 2887 CU_ASSERT(g_bserrno == 0); 2888 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2889 2890 /* Unload the blob store */ 2891 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2892 poll_threads(); 2893 CU_ASSERT(g_bserrno == 0); 2894 g_bs = NULL; 2895 g_blob = NULL; 2896 g_blobid = 0; 2897 2898 /* Load an existing blob store with version newer than supported */ 2899 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2900 super_block->version++; 2901 2902 dev = init_dev(); 2903 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2904 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2905 poll_threads(); 2906 CU_ASSERT(g_bserrno != 0); 2907 2908 /* Create a new blob store with super block version 1 */ 2909 dev = init_dev(); 2910 super_block_v1.version = 1; 2911 memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 2912 super_block_v1.length = 0x1000; 2913 super_block_v1.clean = 1; 2914 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 2915 super_block_v1.cluster_size = 0x100000; 2916 super_block_v1.used_page_mask_start = 0x01; 2917 super_block_v1.used_page_mask_len = 0x01; 2918 super_block_v1.used_cluster_mask_start = 0x02; 2919 super_block_v1.used_cluster_mask_len = 0x01; 2920 super_block_v1.md_start = 0x03; 2921 super_block_v1.md_len = 0x40; 2922 memset(super_block_v1.reserved, 0, 4036); 2923 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 2924 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 2925 2926 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2927 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2928 poll_threads(); 2929 CU_ASSERT(g_bserrno == 0); 2930 2931 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2932 poll_threads(); 2933 CU_ASSERT(g_bserrno == 0); 2934 g_bs = NULL; 2935 } 2936 2937 /* 2938 * Create a blobstore and then unload it. 2939 */ 2940 static void 2941 bs_unload(void) 2942 { 2943 struct spdk_bs_dev *dev; 2944 struct spdk_blob_store *bs; 2945 spdk_blob_id blobid; 2946 struct spdk_blob *blob; 2947 2948 dev = init_dev(); 2949 2950 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2951 poll_threads(); 2952 CU_ASSERT(g_bserrno == 0); 2953 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2954 bs = g_bs; 2955 2956 /* Create a blob and open it. */ 2957 g_bserrno = -1; 2958 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2959 poll_threads(); 2960 CU_ASSERT(g_bserrno == 0); 2961 CU_ASSERT(g_blobid > 0); 2962 blobid = g_blobid; 2963 2964 g_bserrno = -1; 2965 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2966 poll_threads(); 2967 CU_ASSERT(g_bserrno == 0); 2968 CU_ASSERT(g_blob != NULL); 2969 blob = g_blob; 2970 2971 /* Try to unload blobstore, should fail with open blob */ 2972 g_bserrno = -1; 2973 spdk_bs_unload(bs, bs_op_complete, NULL); 2974 poll_threads(); 2975 CU_ASSERT(g_bserrno == -EBUSY); 2976 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2977 2978 /* Close the blob, then successfully unload blobstore */ 2979 g_bserrno = -1; 2980 spdk_blob_close(blob, blob_op_complete, NULL); 2981 poll_threads(); 2982 CU_ASSERT(g_bserrno == 0); 2983 2984 g_bserrno = -1; 2985 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2986 poll_threads(); 2987 CU_ASSERT(g_bserrno == 0); 2988 g_bs = NULL; 2989 } 2990 2991 /* 2992 * Create a blobstore with a cluster size different than the default, and ensure it is 2993 * persisted. 2994 */ 2995 static void 2996 bs_cluster_sz(void) 2997 { 2998 struct spdk_bs_dev *dev; 2999 struct spdk_bs_opts opts; 3000 uint32_t cluster_sz; 3001 3002 /* Set cluster size to zero */ 3003 dev = init_dev(); 3004 spdk_bs_opts_init(&opts); 3005 opts.cluster_sz = 0; 3006 3007 /* Initialize a new blob store */ 3008 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3009 poll_threads(); 3010 CU_ASSERT(g_bserrno == -EINVAL); 3011 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 3012 3013 /* 3014 * Set cluster size to blobstore page size, 3015 * to work it is required to be at least twice the blobstore page size. 3016 */ 3017 dev = init_dev(); 3018 spdk_bs_opts_init(&opts); 3019 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 3020 3021 /* Initialize a new blob store */ 3022 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3023 poll_threads(); 3024 CU_ASSERT(g_bserrno == -ENOMEM); 3025 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 3026 3027 /* 3028 * Set cluster size to lower than page size, 3029 * to work it is required to be at least twice the blobstore page size. 3030 */ 3031 dev = init_dev(); 3032 spdk_bs_opts_init(&opts); 3033 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 3034 3035 /* Initialize a new blob store */ 3036 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3037 poll_threads(); 3038 CU_ASSERT(g_bserrno == -EINVAL); 3039 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 3040 3041 /* Set cluster size to twice the default */ 3042 dev = init_dev(); 3043 spdk_bs_opts_init(&opts); 3044 opts.cluster_sz *= 2; 3045 cluster_sz = opts.cluster_sz; 3046 3047 /* Initialize a new blob store */ 3048 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3049 poll_threads(); 3050 CU_ASSERT(g_bserrno == 0); 3051 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3052 3053 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 3054 3055 /* Unload the blob store */ 3056 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3057 poll_threads(); 3058 CU_ASSERT(g_bserrno == 0); 3059 g_bs = NULL; 3060 g_blob = NULL; 3061 g_blobid = 0; 3062 3063 dev = init_dev(); 3064 /* Load an existing blob store */ 3065 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3066 poll_threads(); 3067 CU_ASSERT(g_bserrno == 0); 3068 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3069 3070 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 3071 3072 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3073 poll_threads(); 3074 CU_ASSERT(g_bserrno == 0); 3075 g_bs = NULL; 3076 } 3077 3078 /* 3079 * Create a blobstore, reload it and ensure total usable cluster count 3080 * stays the same. 3081 */ 3082 static void 3083 bs_usable_clusters(void) 3084 { 3085 struct spdk_bs_dev *dev; 3086 struct spdk_bs_opts opts; 3087 uint32_t clusters; 3088 int i; 3089 3090 /* Init blobstore */ 3091 dev = init_dev(); 3092 spdk_bs_opts_init(&opts); 3093 3094 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3095 poll_threads(); 3096 CU_ASSERT(g_bserrno == 0); 3097 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3098 3099 clusters = spdk_bs_total_data_cluster_count(g_bs); 3100 3101 /* Unload the blob store */ 3102 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3103 poll_threads(); 3104 CU_ASSERT(g_bserrno == 0); 3105 g_bs = NULL; 3106 3107 dev = init_dev(); 3108 /* Load an existing blob store */ 3109 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3110 poll_threads(); 3111 CU_ASSERT(g_bserrno == 0); 3112 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3113 3114 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 3115 3116 /* Create and resize blobs to make sure that useable cluster count won't change */ 3117 for (i = 0; i < 4; i++) { 3118 g_bserrno = -1; 3119 g_blobid = SPDK_BLOBID_INVALID; 3120 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3121 poll_threads(); 3122 CU_ASSERT(g_bserrno == 0); 3123 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3124 3125 g_bserrno = -1; 3126 g_blob = NULL; 3127 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 3128 poll_threads(); 3129 CU_ASSERT(g_bserrno == 0); 3130 CU_ASSERT(g_blob != NULL); 3131 3132 spdk_blob_resize(g_blob, 10, blob_op_complete, NULL); 3133 poll_threads(); 3134 CU_ASSERT(g_bserrno == 0); 3135 3136 g_bserrno = -1; 3137 spdk_blob_close(g_blob, blob_op_complete, NULL); 3138 poll_threads(); 3139 CU_ASSERT(g_bserrno == 0); 3140 3141 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 3142 } 3143 3144 /* Reload the blob store to make sure that nothing changed */ 3145 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3146 poll_threads(); 3147 CU_ASSERT(g_bserrno == 0); 3148 g_bs = NULL; 3149 3150 dev = init_dev(); 3151 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3152 poll_threads(); 3153 CU_ASSERT(g_bserrno == 0); 3154 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3155 3156 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 3157 3158 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3159 poll_threads(); 3160 CU_ASSERT(g_bserrno == 0); 3161 g_bs = NULL; 3162 } 3163 3164 /* 3165 * Test resizing of the metadata blob. This requires creating enough blobs 3166 * so that one cluster is not enough to fit the metadata for those blobs. 3167 * To induce this condition to happen more quickly, we reduce the cluster 3168 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 3169 */ 3170 static void 3171 bs_resize_md(void) 3172 { 3173 const int CLUSTER_PAGE_COUNT = 4; 3174 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 3175 struct spdk_bs_dev *dev; 3176 struct spdk_bs_opts opts; 3177 uint32_t cluster_sz; 3178 spdk_blob_id blobids[NUM_BLOBS]; 3179 int i; 3180 3181 3182 dev = init_dev(); 3183 spdk_bs_opts_init(&opts); 3184 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 3185 cluster_sz = opts.cluster_sz; 3186 3187 /* Initialize a new blob store */ 3188 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3189 poll_threads(); 3190 CU_ASSERT(g_bserrno == 0); 3191 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3192 3193 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 3194 3195 for (i = 0; i < NUM_BLOBS; i++) { 3196 g_bserrno = -1; 3197 g_blobid = SPDK_BLOBID_INVALID; 3198 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3199 poll_threads(); 3200 CU_ASSERT(g_bserrno == 0); 3201 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3202 blobids[i] = g_blobid; 3203 } 3204 3205 /* Unload the blob store */ 3206 g_bserrno = -1; 3207 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3208 poll_threads(); 3209 CU_ASSERT(g_bserrno == 0); 3210 3211 /* Load an existing blob store */ 3212 g_bserrno = -1; 3213 g_bs = NULL; 3214 dev = init_dev(); 3215 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3216 poll_threads(); 3217 CU_ASSERT(g_bserrno == 0); 3218 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3219 3220 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 3221 3222 for (i = 0; i < NUM_BLOBS; i++) { 3223 g_bserrno = -1; 3224 g_blob = NULL; 3225 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 3226 poll_threads(); 3227 CU_ASSERT(g_bserrno == 0); 3228 CU_ASSERT(g_blob != NULL); 3229 g_bserrno = -1; 3230 spdk_blob_close(g_blob, blob_op_complete, NULL); 3231 poll_threads(); 3232 CU_ASSERT(g_bserrno == 0); 3233 } 3234 3235 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3236 poll_threads(); 3237 CU_ASSERT(g_bserrno == 0); 3238 g_bs = NULL; 3239 } 3240 3241 static void 3242 bs_destroy(void) 3243 { 3244 struct spdk_bs_dev *dev; 3245 struct spdk_bs_opts opts; 3246 3247 /* Initialize a new blob store */ 3248 dev = init_dev(); 3249 spdk_bs_opts_init(&opts); 3250 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3251 poll_threads(); 3252 CU_ASSERT(g_bserrno == 0); 3253 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3254 3255 /* Destroy the blob store */ 3256 g_bserrno = -1; 3257 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 3258 poll_threads(); 3259 CU_ASSERT(g_bserrno == 0); 3260 3261 /* Loading an non-existent blob store should fail. */ 3262 g_bs = NULL; 3263 dev = init_dev(); 3264 3265 g_bserrno = 0; 3266 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3267 poll_threads(); 3268 CU_ASSERT(g_bserrno != 0); 3269 } 3270 3271 /* Try to hit all of the corner cases associated with serializing 3272 * a blob to disk 3273 */ 3274 static void 3275 blob_serialize(void) 3276 { 3277 struct spdk_bs_dev *dev; 3278 struct spdk_bs_opts opts; 3279 struct spdk_blob_store *bs; 3280 spdk_blob_id blobid[2]; 3281 struct spdk_blob *blob[2]; 3282 uint64_t i; 3283 char *value; 3284 int rc; 3285 3286 dev = init_dev(); 3287 3288 /* Initialize a new blobstore with very small clusters */ 3289 spdk_bs_opts_init(&opts); 3290 opts.cluster_sz = dev->blocklen * 8; 3291 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3292 poll_threads(); 3293 CU_ASSERT(g_bserrno == 0); 3294 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3295 bs = g_bs; 3296 3297 /* Create and open two blobs */ 3298 for (i = 0; i < 2; i++) { 3299 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 3300 poll_threads(); 3301 CU_ASSERT(g_bserrno == 0); 3302 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3303 blobid[i] = g_blobid; 3304 3305 /* Open a blob */ 3306 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 3307 poll_threads(); 3308 CU_ASSERT(g_bserrno == 0); 3309 CU_ASSERT(g_blob != NULL); 3310 blob[i] = g_blob; 3311 3312 /* Set a fairly large xattr on both blobs to eat up 3313 * metadata space 3314 */ 3315 value = calloc(dev->blocklen - 64, sizeof(char)); 3316 SPDK_CU_ASSERT_FATAL(value != NULL); 3317 memset(value, i, dev->blocklen / 2); 3318 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 3319 CU_ASSERT(rc == 0); 3320 free(value); 3321 } 3322 3323 /* Resize the blobs, alternating 1 cluster at a time. 3324 * This thwarts run length encoding and will cause spill 3325 * over of the extents. 3326 */ 3327 for (i = 0; i < 6; i++) { 3328 spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL); 3329 poll_threads(); 3330 CU_ASSERT(g_bserrno == 0); 3331 } 3332 3333 for (i = 0; i < 2; i++) { 3334 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 3335 poll_threads(); 3336 CU_ASSERT(g_bserrno == 0); 3337 } 3338 3339 /* Close the blobs */ 3340 for (i = 0; i < 2; i++) { 3341 spdk_blob_close(blob[i], blob_op_complete, NULL); 3342 poll_threads(); 3343 CU_ASSERT(g_bserrno == 0); 3344 } 3345 3346 /* Unload the blobstore */ 3347 spdk_bs_unload(bs, bs_op_complete, NULL); 3348 poll_threads(); 3349 CU_ASSERT(g_bserrno == 0); 3350 g_bs = NULL; 3351 g_blob = NULL; 3352 g_blobid = 0; 3353 bs = NULL; 3354 3355 dev = init_dev(); 3356 /* Load an existing blob store */ 3357 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3358 poll_threads(); 3359 CU_ASSERT(g_bserrno == 0); 3360 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3361 bs = g_bs; 3362 3363 for (i = 0; i < 2; i++) { 3364 blob[i] = NULL; 3365 3366 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 3367 poll_threads(); 3368 CU_ASSERT(g_bserrno == 0); 3369 CU_ASSERT(g_blob != NULL); 3370 blob[i] = g_blob; 3371 3372 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 3373 3374 spdk_blob_close(blob[i], blob_op_complete, NULL); 3375 poll_threads(); 3376 CU_ASSERT(g_bserrno == 0); 3377 } 3378 3379 spdk_bs_unload(bs, bs_op_complete, NULL); 3380 poll_threads(); 3381 CU_ASSERT(g_bserrno == 0); 3382 g_bs = NULL; 3383 } 3384 3385 static void 3386 blob_crc(void) 3387 { 3388 struct spdk_blob_store *bs; 3389 struct spdk_bs_dev *dev; 3390 struct spdk_blob *blob; 3391 spdk_blob_id blobid; 3392 uint32_t page_num; 3393 int index; 3394 struct spdk_blob_md_page *page; 3395 3396 dev = init_dev(); 3397 3398 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3399 poll_threads(); 3400 CU_ASSERT(g_bserrno == 0); 3401 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3402 bs = g_bs; 3403 3404 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 3405 poll_threads(); 3406 CU_ASSERT(g_bserrno == 0); 3407 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3408 blobid = g_blobid; 3409 3410 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3411 poll_threads(); 3412 CU_ASSERT(g_bserrno == 0); 3413 CU_ASSERT(g_blob != NULL); 3414 blob = g_blob; 3415 3416 spdk_blob_close(blob, blob_op_complete, NULL); 3417 poll_threads(); 3418 CU_ASSERT(g_bserrno == 0); 3419 3420 page_num = _spdk_bs_blobid_to_page(blobid); 3421 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 3422 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3423 page->crc = 0; 3424 3425 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3426 poll_threads(); 3427 CU_ASSERT(g_bserrno == -EINVAL); 3428 CU_ASSERT(g_blob == NULL); 3429 g_bserrno = 0; 3430 3431 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3432 poll_threads(); 3433 CU_ASSERT(g_bserrno == -EINVAL); 3434 3435 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3436 poll_threads(); 3437 CU_ASSERT(g_bserrno == 0); 3438 g_bs = NULL; 3439 } 3440 3441 static void 3442 super_block_crc(void) 3443 { 3444 struct spdk_bs_dev *dev; 3445 struct spdk_bs_super_block *super_block; 3446 struct spdk_bs_opts opts; 3447 3448 dev = init_dev(); 3449 spdk_bs_opts_init(&opts); 3450 3451 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3452 poll_threads(); 3453 CU_ASSERT(g_bserrno == 0); 3454 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3455 3456 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3457 poll_threads(); 3458 CU_ASSERT(g_bserrno == 0); 3459 g_bs = NULL; 3460 3461 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 3462 super_block->crc = 0; 3463 dev = init_dev(); 3464 3465 /* Load an existing blob store */ 3466 g_bserrno = 0; 3467 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3468 poll_threads(); 3469 CU_ASSERT(g_bserrno == -EILSEQ); 3470 } 3471 3472 /* For blob dirty shutdown test case we do the following sub-test cases: 3473 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we 3474 * dirty shutdown and reload the blob store and verify the xattrs. 3475 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 3476 * reload the blob store and verify the clusters number. 3477 * 3 Create the second blob and then dirty shutdown, reload the blob store 3478 * and verify the second blob. 3479 * 4 Delete the second blob and then dirty shutdown, reload the blob store 3480 * and verify the second blob is invalid. 3481 * 5 Create the second blob again and also create the third blob, modify the 3482 * md of second blob which makes the md invalid, and then dirty shutdown, 3483 * reload the blob store verify the second blob, it should invalid and also 3484 * verify the third blob, it should correct. 3485 */ 3486 static void 3487 blob_dirty_shutdown(void) 3488 { 3489 int rc; 3490 int index; 3491 struct spdk_bs_dev *dev; 3492 spdk_blob_id blobid1, blobid2, blobid3; 3493 struct spdk_blob *blob; 3494 uint64_t length; 3495 uint64_t free_clusters; 3496 const void *value; 3497 size_t value_len; 3498 uint32_t page_num; 3499 struct spdk_blob_md_page *page; 3500 struct spdk_bs_opts opts; 3501 3502 dev = init_dev(); 3503 spdk_bs_opts_init(&opts); 3504 /* Initialize a new blob store */ 3505 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3506 poll_threads(); 3507 CU_ASSERT(g_bserrno == 0); 3508 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3509 3510 /* Create first blob */ 3511 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3512 poll_threads(); 3513 CU_ASSERT(g_bserrno == 0); 3514 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3515 blobid1 = g_blobid; 3516 3517 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3518 poll_threads(); 3519 CU_ASSERT(g_bserrno == 0); 3520 CU_ASSERT(g_blob != NULL); 3521 blob = g_blob; 3522 3523 /* Set some xattrs */ 3524 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 3525 CU_ASSERT(rc == 0); 3526 3527 length = 2345; 3528 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3529 CU_ASSERT(rc == 0); 3530 3531 /* Resize the blob */ 3532 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3533 poll_threads(); 3534 CU_ASSERT(g_bserrno == 0); 3535 3536 /* Set the blob as the super blob */ 3537 spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL); 3538 poll_threads(); 3539 CU_ASSERT(g_bserrno == 0); 3540 3541 free_clusters = spdk_bs_free_cluster_count(g_bs); 3542 3543 spdk_blob_close(blob, blob_op_complete, NULL); 3544 blob = NULL; 3545 g_blob = NULL; 3546 g_blobid = SPDK_BLOBID_INVALID; 3547 3548 /* Dirty shutdown */ 3549 _spdk_bs_free(g_bs); 3550 3551 /* reload blobstore */ 3552 dev = init_dev(); 3553 spdk_bs_opts_init(&opts); 3554 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3555 poll_threads(); 3556 CU_ASSERT(g_bserrno == 0); 3557 3558 /* Get the super blob */ 3559 spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL); 3560 poll_threads(); 3561 CU_ASSERT(g_bserrno == 0); 3562 CU_ASSERT(blobid1 == g_blobid); 3563 3564 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3565 poll_threads(); 3566 CU_ASSERT(g_bserrno == 0); 3567 CU_ASSERT(g_blob != NULL); 3568 blob = g_blob; 3569 3570 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3571 3572 /* Get the xattrs */ 3573 value = NULL; 3574 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3575 CU_ASSERT(rc == 0); 3576 SPDK_CU_ASSERT_FATAL(value != NULL); 3577 CU_ASSERT(*(uint64_t *)value == length); 3578 CU_ASSERT(value_len == 8); 3579 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3580 3581 /* Resize the blob */ 3582 spdk_blob_resize(blob, 20, blob_op_complete, NULL); 3583 poll_threads(); 3584 CU_ASSERT(g_bserrno == 0); 3585 3586 free_clusters = spdk_bs_free_cluster_count(g_bs); 3587 3588 spdk_blob_close(blob, blob_op_complete, NULL); 3589 poll_threads(); 3590 CU_ASSERT(g_bserrno == 0); 3591 blob = NULL; 3592 g_blob = NULL; 3593 g_blobid = SPDK_BLOBID_INVALID; 3594 3595 /* Dirty shutdown */ 3596 _spdk_bs_free(g_bs); 3597 3598 /* reload the blobstore */ 3599 dev = init_dev(); 3600 spdk_bs_opts_init(&opts); 3601 /* Load an existing blob store */ 3602 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3603 poll_threads(); 3604 CU_ASSERT(g_bserrno == 0); 3605 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3606 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3607 poll_threads(); 3608 CU_ASSERT(g_bserrno == 0); 3609 CU_ASSERT(g_blob != NULL); 3610 blob = g_blob; 3611 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 3612 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3613 3614 spdk_blob_close(blob, blob_op_complete, NULL); 3615 poll_threads(); 3616 CU_ASSERT(g_bserrno == 0); 3617 blob = NULL; 3618 g_blob = NULL; 3619 g_blobid = SPDK_BLOBID_INVALID; 3620 3621 /* Create second blob */ 3622 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3623 poll_threads(); 3624 CU_ASSERT(g_bserrno == 0); 3625 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3626 blobid2 = g_blobid; 3627 3628 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3629 poll_threads(); 3630 CU_ASSERT(g_bserrno == 0); 3631 CU_ASSERT(g_blob != NULL); 3632 blob = g_blob; 3633 3634 /* Set some xattrs */ 3635 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3636 CU_ASSERT(rc == 0); 3637 3638 length = 5432; 3639 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3640 CU_ASSERT(rc == 0); 3641 3642 /* Resize the blob */ 3643 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3644 poll_threads(); 3645 CU_ASSERT(g_bserrno == 0); 3646 3647 free_clusters = spdk_bs_free_cluster_count(g_bs); 3648 3649 spdk_blob_close(blob, blob_op_complete, NULL); 3650 blob = NULL; 3651 g_blob = NULL; 3652 g_blobid = SPDK_BLOBID_INVALID; 3653 3654 /* Dirty shutdown */ 3655 _spdk_bs_free(g_bs); 3656 3657 /* reload the blobstore */ 3658 dev = init_dev(); 3659 spdk_bs_opts_init(&opts); 3660 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3661 poll_threads(); 3662 CU_ASSERT(g_bserrno == 0); 3663 3664 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3665 poll_threads(); 3666 CU_ASSERT(g_bserrno == 0); 3667 CU_ASSERT(g_blob != NULL); 3668 blob = g_blob; 3669 3670 /* Get the xattrs */ 3671 value = NULL; 3672 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3673 CU_ASSERT(rc == 0); 3674 SPDK_CU_ASSERT_FATAL(value != NULL); 3675 CU_ASSERT(*(uint64_t *)value == length); 3676 CU_ASSERT(value_len == 8); 3677 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3678 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3679 3680 spdk_blob_close(blob, blob_op_complete, NULL); 3681 poll_threads(); 3682 CU_ASSERT(g_bserrno == 0); 3683 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 3684 poll_threads(); 3685 CU_ASSERT(g_bserrno == 0); 3686 3687 free_clusters = spdk_bs_free_cluster_count(g_bs); 3688 3689 /* Dirty shutdown */ 3690 _spdk_bs_free(g_bs); 3691 /* reload the blobstore */ 3692 dev = init_dev(); 3693 spdk_bs_opts_init(&opts); 3694 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3695 poll_threads(); 3696 CU_ASSERT(g_bserrno == 0); 3697 3698 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3699 poll_threads(); 3700 CU_ASSERT(g_bserrno != 0); 3701 CU_ASSERT(g_blob == NULL); 3702 3703 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3704 poll_threads(); 3705 CU_ASSERT(g_bserrno == 0); 3706 CU_ASSERT(g_blob != NULL); 3707 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3708 spdk_blob_close(g_blob, blob_op_complete, NULL); 3709 poll_threads(); 3710 CU_ASSERT(g_bserrno == 0); 3711 3712 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3713 poll_threads(); 3714 CU_ASSERT(g_bserrno == 0); 3715 g_bs = NULL; 3716 3717 /* reload the blobstore */ 3718 dev = init_dev(); 3719 spdk_bs_opts_init(&opts); 3720 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3721 poll_threads(); 3722 CU_ASSERT(g_bserrno == 0); 3723 3724 /* Create second blob */ 3725 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3726 poll_threads(); 3727 CU_ASSERT(g_bserrno == 0); 3728 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3729 blobid2 = g_blobid; 3730 3731 /* Create third blob */ 3732 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3733 poll_threads(); 3734 CU_ASSERT(g_bserrno == 0); 3735 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3736 blobid3 = g_blobid; 3737 3738 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3739 poll_threads(); 3740 CU_ASSERT(g_bserrno == 0); 3741 CU_ASSERT(g_blob != NULL); 3742 blob = g_blob; 3743 3744 /* Set some xattrs for second blob */ 3745 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3746 CU_ASSERT(rc == 0); 3747 3748 length = 5432; 3749 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3750 CU_ASSERT(rc == 0); 3751 3752 spdk_blob_close(blob, blob_op_complete, NULL); 3753 poll_threads(); 3754 blob = NULL; 3755 g_blob = NULL; 3756 g_blobid = SPDK_BLOBID_INVALID; 3757 3758 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 3759 poll_threads(); 3760 CU_ASSERT(g_bserrno == 0); 3761 CU_ASSERT(g_blob != NULL); 3762 blob = g_blob; 3763 3764 /* Set some xattrs for third blob */ 3765 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 3766 CU_ASSERT(rc == 0); 3767 3768 length = 5432; 3769 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3770 CU_ASSERT(rc == 0); 3771 3772 spdk_blob_close(blob, blob_op_complete, NULL); 3773 poll_threads(); 3774 blob = NULL; 3775 g_blob = NULL; 3776 g_blobid = SPDK_BLOBID_INVALID; 3777 3778 /* Mark second blob as invalid */ 3779 page_num = _spdk_bs_blobid_to_page(blobid2); 3780 3781 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 3782 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3783 page->sequence_num = 1; 3784 page->crc = _spdk_blob_md_page_calc_crc(page); 3785 3786 free_clusters = spdk_bs_free_cluster_count(g_bs); 3787 3788 /* Dirty shutdown */ 3789 _spdk_bs_free(g_bs); 3790 /* reload the blobstore */ 3791 dev = init_dev(); 3792 spdk_bs_opts_init(&opts); 3793 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3794 poll_threads(); 3795 CU_ASSERT(g_bserrno == 0); 3796 3797 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3798 poll_threads(); 3799 CU_ASSERT(g_bserrno != 0); 3800 CU_ASSERT(g_blob == NULL); 3801 3802 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 3803 poll_threads(); 3804 CU_ASSERT(g_bserrno == 0); 3805 CU_ASSERT(g_blob != NULL); 3806 blob = g_blob; 3807 3808 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3809 3810 spdk_blob_close(blob, blob_op_complete, NULL); 3811 blob = NULL; 3812 g_blob = NULL; 3813 g_blobid = SPDK_BLOBID_INVALID; 3814 3815 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3816 poll_threads(); 3817 CU_ASSERT(g_bserrno == 0); 3818 g_bs = NULL; 3819 } 3820 3821 static void 3822 blob_flags(void) 3823 { 3824 struct spdk_bs_dev *dev; 3825 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 3826 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 3827 struct spdk_bs_opts opts; 3828 int rc; 3829 3830 dev = init_dev(); 3831 spdk_bs_opts_init(&opts); 3832 3833 /* Initialize a new blob store */ 3834 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3835 poll_threads(); 3836 CU_ASSERT(g_bserrno == 0); 3837 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3838 3839 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 3840 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3841 poll_threads(); 3842 CU_ASSERT(g_bserrno == 0); 3843 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3844 blobid_invalid = g_blobid; 3845 3846 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3847 poll_threads(); 3848 CU_ASSERT(g_bserrno == 0); 3849 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3850 blobid_data_ro = g_blobid; 3851 3852 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3853 poll_threads(); 3854 CU_ASSERT(g_bserrno == 0); 3855 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3856 blobid_md_ro = g_blobid; 3857 3858 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 3859 poll_threads(); 3860 CU_ASSERT(g_bserrno == 0); 3861 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3862 blob_invalid = g_blob; 3863 3864 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 3865 poll_threads(); 3866 CU_ASSERT(g_bserrno == 0); 3867 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3868 blob_data_ro = g_blob; 3869 3870 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 3871 poll_threads(); 3872 CU_ASSERT(g_bserrno == 0); 3873 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3874 blob_md_ro = g_blob; 3875 3876 /* Change the size of blob_data_ro to check if flags are serialized 3877 * when blob has non zero number of extents */ 3878 spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL); 3879 poll_threads(); 3880 CU_ASSERT(g_bserrno == 0); 3881 3882 /* Set the xattr to check if flags are serialized 3883 * when blob has non zero number of xattrs */ 3884 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 3885 CU_ASSERT(rc == 0); 3886 3887 blob_invalid->invalid_flags = (1ULL << 63); 3888 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 3889 blob_data_ro->data_ro_flags = (1ULL << 62); 3890 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 3891 blob_md_ro->md_ro_flags = (1ULL << 61); 3892 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 3893 3894 g_bserrno = -1; 3895 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 3896 poll_threads(); 3897 CU_ASSERT(g_bserrno == 0); 3898 g_bserrno = -1; 3899 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 3900 poll_threads(); 3901 CU_ASSERT(g_bserrno == 0); 3902 g_bserrno = -1; 3903 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 3904 poll_threads(); 3905 CU_ASSERT(g_bserrno == 0); 3906 3907 g_bserrno = -1; 3908 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 3909 poll_threads(); 3910 CU_ASSERT(g_bserrno == 0); 3911 blob_invalid = NULL; 3912 g_bserrno = -1; 3913 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 3914 poll_threads(); 3915 CU_ASSERT(g_bserrno == 0); 3916 blob_data_ro = NULL; 3917 g_bserrno = -1; 3918 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 3919 poll_threads(); 3920 CU_ASSERT(g_bserrno == 0); 3921 blob_md_ro = NULL; 3922 3923 g_blob = NULL; 3924 g_blobid = SPDK_BLOBID_INVALID; 3925 3926 /* Unload the blob store */ 3927 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3928 poll_threads(); 3929 CU_ASSERT(g_bserrno == 0); 3930 g_bs = NULL; 3931 3932 /* Load an existing blob store */ 3933 dev = init_dev(); 3934 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3935 poll_threads(); 3936 CU_ASSERT(g_bserrno == 0); 3937 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3938 3939 g_blob = NULL; 3940 g_bserrno = 0; 3941 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 3942 poll_threads(); 3943 CU_ASSERT(g_bserrno != 0); 3944 CU_ASSERT(g_blob == NULL); 3945 3946 g_blob = NULL; 3947 g_bserrno = -1; 3948 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 3949 poll_threads(); 3950 CU_ASSERT(g_bserrno == 0); 3951 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3952 blob_data_ro = g_blob; 3953 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 3954 CU_ASSERT(blob_data_ro->data_ro == true); 3955 CU_ASSERT(blob_data_ro->md_ro == true); 3956 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 3957 3958 g_blob = NULL; 3959 g_bserrno = -1; 3960 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 3961 poll_threads(); 3962 CU_ASSERT(g_bserrno == 0); 3963 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3964 blob_md_ro = g_blob; 3965 CU_ASSERT(blob_md_ro->data_ro == false); 3966 CU_ASSERT(blob_md_ro->md_ro == true); 3967 3968 g_bserrno = -1; 3969 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 3970 poll_threads(); 3971 CU_ASSERT(g_bserrno == 0); 3972 3973 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 3974 poll_threads(); 3975 CU_ASSERT(g_bserrno == 0); 3976 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 3977 poll_threads(); 3978 CU_ASSERT(g_bserrno == 0); 3979 3980 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3981 poll_threads(); 3982 CU_ASSERT(g_bserrno == 0); 3983 } 3984 3985 static void 3986 bs_version(void) 3987 { 3988 struct spdk_bs_super_block *super; 3989 struct spdk_bs_dev *dev; 3990 struct spdk_bs_opts opts; 3991 spdk_blob_id blobid; 3992 3993 dev = init_dev(); 3994 spdk_bs_opts_init(&opts); 3995 3996 /* Initialize a new blob store */ 3997 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3998 poll_threads(); 3999 CU_ASSERT(g_bserrno == 0); 4000 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4001 4002 /* Unload the blob store */ 4003 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4004 poll_threads(); 4005 CU_ASSERT(g_bserrno == 0); 4006 g_bs = NULL; 4007 4008 /* 4009 * Change the bs version on disk. This will allow us to 4010 * test that the version does not get modified automatically 4011 * when loading and unloading the blobstore. 4012 */ 4013 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 4014 CU_ASSERT(super->version == SPDK_BS_VERSION); 4015 CU_ASSERT(super->clean == 1); 4016 super->version = 2; 4017 /* 4018 * Version 2 metadata does not have a used blobid mask, so clear 4019 * those fields in the super block and zero the corresponding 4020 * region on "disk". We will use this to ensure blob IDs are 4021 * correctly reconstructed. 4022 */ 4023 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 4024 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 4025 super->used_blobid_mask_start = 0; 4026 super->used_blobid_mask_len = 0; 4027 super->crc = _spdk_blob_md_page_calc_crc(super); 4028 4029 /* Load an existing blob store */ 4030 dev = init_dev(); 4031 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4032 poll_threads(); 4033 CU_ASSERT(g_bserrno == 0); 4034 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4035 CU_ASSERT(super->clean == 1); 4036 4037 /* 4038 * Create a blob - just to make sure that when we unload it 4039 * results in writing the super block (since metadata pages 4040 * were allocated. 4041 */ 4042 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 4043 poll_threads(); 4044 CU_ASSERT(g_bserrno == 0); 4045 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4046 blobid = g_blobid; 4047 4048 /* Unload the blob store */ 4049 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4050 poll_threads(); 4051 CU_ASSERT(g_bserrno == 0); 4052 g_bs = NULL; 4053 CU_ASSERT(super->version == 2); 4054 CU_ASSERT(super->used_blobid_mask_start == 0); 4055 CU_ASSERT(super->used_blobid_mask_len == 0); 4056 4057 dev = init_dev(); 4058 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4059 poll_threads(); 4060 CU_ASSERT(g_bserrno == 0); 4061 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4062 4063 g_blob = NULL; 4064 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 4065 poll_threads(); 4066 CU_ASSERT(g_bserrno == 0); 4067 CU_ASSERT(g_blob != NULL); 4068 4069 spdk_blob_close(g_blob, blob_op_complete, NULL); 4070 poll_threads(); 4071 CU_ASSERT(g_bserrno == 0); 4072 4073 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4074 poll_threads(); 4075 CU_ASSERT(g_bserrno == 0); 4076 g_bs = NULL; 4077 CU_ASSERT(super->version == 2); 4078 CU_ASSERT(super->used_blobid_mask_start == 0); 4079 CU_ASSERT(super->used_blobid_mask_len == 0); 4080 } 4081 4082 static void 4083 blob_set_xattrs(void) 4084 { 4085 struct spdk_blob_store *bs; 4086 struct spdk_bs_dev *dev; 4087 struct spdk_blob *blob; 4088 struct spdk_blob_opts opts; 4089 spdk_blob_id blobid; 4090 const void *value; 4091 size_t value_len; 4092 int rc; 4093 4094 dev = init_dev(); 4095 4096 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4097 poll_threads(); 4098 CU_ASSERT(g_bserrno == 0); 4099 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4100 bs = g_bs; 4101 4102 /* Create blob with extra attributes */ 4103 spdk_blob_opts_init(&opts); 4104 4105 opts.xattrs.names = g_xattr_names; 4106 opts.xattrs.get_value = _get_xattr_value; 4107 opts.xattrs.count = 3; 4108 opts.xattrs.ctx = &g_ctx; 4109 4110 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4111 poll_threads(); 4112 CU_ASSERT(g_bserrno == 0); 4113 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4114 blobid = g_blobid; 4115 4116 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4117 poll_threads(); 4118 CU_ASSERT(g_bserrno == 0); 4119 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4120 blob = g_blob; 4121 4122 /* Get the xattrs */ 4123 value = NULL; 4124 4125 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 4126 CU_ASSERT(rc == 0); 4127 SPDK_CU_ASSERT_FATAL(value != NULL); 4128 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 4129 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 4130 4131 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 4132 CU_ASSERT(rc == 0); 4133 SPDK_CU_ASSERT_FATAL(value != NULL); 4134 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 4135 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 4136 4137 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 4138 CU_ASSERT(rc == 0); 4139 SPDK_CU_ASSERT_FATAL(value != NULL); 4140 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 4141 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 4142 4143 /* Try to get non existing attribute */ 4144 4145 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 4146 CU_ASSERT(rc == -ENOENT); 4147 4148 spdk_blob_close(blob, blob_op_complete, NULL); 4149 poll_threads(); 4150 CU_ASSERT(g_bserrno == 0); 4151 blob = NULL; 4152 g_blob = NULL; 4153 g_blobid = SPDK_BLOBID_INVALID; 4154 4155 /* NULL callback */ 4156 spdk_blob_opts_init(&opts); 4157 opts.xattrs.names = g_xattr_names; 4158 opts.xattrs.get_value = NULL; 4159 opts.xattrs.count = 1; 4160 opts.xattrs.ctx = &g_ctx; 4161 4162 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4163 poll_threads(); 4164 CU_ASSERT(g_bserrno == -EINVAL); 4165 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4166 4167 /* NULL values */ 4168 spdk_blob_opts_init(&opts); 4169 opts.xattrs.names = g_xattr_names; 4170 opts.xattrs.get_value = _get_xattr_value_null; 4171 opts.xattrs.count = 1; 4172 opts.xattrs.ctx = NULL; 4173 4174 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4175 poll_threads(); 4176 CU_ASSERT(g_bserrno == -EINVAL); 4177 4178 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4179 poll_threads(); 4180 CU_ASSERT(g_bserrno == 0); 4181 g_bs = NULL; 4182 4183 } 4184 4185 static void 4186 blob_thin_prov_alloc(void) 4187 { 4188 struct spdk_blob_store *bs; 4189 struct spdk_bs_dev *dev; 4190 struct spdk_blob *blob; 4191 struct spdk_blob_opts opts; 4192 spdk_blob_id blobid; 4193 uint64_t free_clusters; 4194 4195 dev = init_dev(); 4196 4197 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4198 poll_threads(); 4199 CU_ASSERT(g_bserrno == 0); 4200 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4201 bs = g_bs; 4202 free_clusters = spdk_bs_free_cluster_count(bs); 4203 4204 /* Set blob as thin provisioned */ 4205 spdk_blob_opts_init(&opts); 4206 opts.thin_provision = true; 4207 4208 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4209 poll_threads(); 4210 CU_ASSERT(g_bserrno == 0); 4211 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4212 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4213 blobid = g_blobid; 4214 4215 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4216 poll_threads(); 4217 CU_ASSERT(g_bserrno == 0); 4218 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4219 blob = g_blob; 4220 4221 CU_ASSERT(blob->active.num_clusters == 0); 4222 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 4223 4224 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4225 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4226 poll_threads(); 4227 CU_ASSERT(g_bserrno == 0); 4228 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4229 CU_ASSERT(blob->active.num_clusters == 5); 4230 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4231 4232 /* Grow it to 1TB - still unallocated */ 4233 spdk_blob_resize(blob, 262144, blob_op_complete, NULL); 4234 poll_threads(); 4235 CU_ASSERT(g_bserrno == 0); 4236 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4237 CU_ASSERT(blob->active.num_clusters == 262144); 4238 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 4239 4240 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4241 poll_threads(); 4242 CU_ASSERT(g_bserrno == 0); 4243 /* Sync must not change anything */ 4244 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4245 CU_ASSERT(blob->active.num_clusters == 262144); 4246 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 4247 /* Since clusters are not allocated, 4248 * number of metadata pages is expected to be minimal. 4249 */ 4250 CU_ASSERT(blob->active.num_pages == 1); 4251 4252 /* Shrink the blob to 3 clusters - still unallocated */ 4253 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 4254 poll_threads(); 4255 CU_ASSERT(g_bserrno == 0); 4256 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4257 CU_ASSERT(blob->active.num_clusters == 3); 4258 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 4259 4260 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4261 poll_threads(); 4262 CU_ASSERT(g_bserrno == 0); 4263 /* Sync must not change anything */ 4264 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4265 CU_ASSERT(blob->active.num_clusters == 3); 4266 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 4267 4268 spdk_blob_close(blob, blob_op_complete, NULL); 4269 poll_threads(); 4270 CU_ASSERT(g_bserrno == 0); 4271 4272 /* Unload the blob store */ 4273 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4274 poll_threads(); 4275 CU_ASSERT(g_bserrno == 0); 4276 g_bs = NULL; 4277 g_blob = NULL; 4278 g_blobid = 0; 4279 4280 /* Load an existing blob store */ 4281 dev = init_dev(); 4282 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4283 poll_threads(); 4284 CU_ASSERT(g_bserrno == 0); 4285 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4286 4287 bs = g_bs; 4288 4289 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 4290 poll_threads(); 4291 CU_ASSERT(g_bserrno == 0); 4292 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4293 blob = g_blob; 4294 4295 /* Check that clusters allocation and size is still the same */ 4296 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4297 CU_ASSERT(blob->active.num_clusters == 3); 4298 4299 spdk_blob_close(blob, blob_op_complete, NULL); 4300 poll_threads(); 4301 CU_ASSERT(g_bserrno == 0); 4302 4303 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4304 poll_threads(); 4305 CU_ASSERT(g_bserrno == 0); 4306 4307 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4308 poll_threads(); 4309 CU_ASSERT(g_bserrno == 0); 4310 g_bs = NULL; 4311 } 4312 4313 static void 4314 blob_insert_cluster_msg(void) 4315 { 4316 struct spdk_blob_store *bs; 4317 struct spdk_bs_dev *dev; 4318 struct spdk_blob *blob; 4319 struct spdk_blob_opts opts; 4320 spdk_blob_id blobid; 4321 uint64_t free_clusters; 4322 4323 dev = init_dev(); 4324 4325 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4326 poll_threads(); 4327 CU_ASSERT(g_bserrno == 0); 4328 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4329 bs = g_bs; 4330 free_clusters = spdk_bs_free_cluster_count(bs); 4331 4332 /* Set blob as thin provisioned */ 4333 spdk_blob_opts_init(&opts); 4334 opts.thin_provision = true; 4335 opts.num_clusters = 4; 4336 4337 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4338 poll_threads(); 4339 CU_ASSERT(g_bserrno == 0); 4340 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4341 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4342 blobid = g_blobid; 4343 4344 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4345 poll_threads(); 4346 CU_ASSERT(g_bserrno == 0); 4347 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4348 blob = g_blob; 4349 4350 CU_ASSERT(blob->active.num_clusters == 4); 4351 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 4352 CU_ASSERT(blob->active.clusters[1] == 0); 4353 4354 _spdk_bs_claim_cluster(bs, 0xF); 4355 _spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL); 4356 poll_threads(); 4357 4358 CU_ASSERT(blob->active.clusters[1] != 0); 4359 4360 spdk_blob_close(blob, blob_op_complete, NULL); 4361 poll_threads(); 4362 CU_ASSERT(g_bserrno == 0); 4363 4364 /* Unload the blob store */ 4365 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4366 poll_threads(); 4367 CU_ASSERT(g_bserrno == 0); 4368 g_bs = NULL; 4369 g_blob = NULL; 4370 g_blobid = 0; 4371 4372 /* Load an existing blob store */ 4373 dev = init_dev(); 4374 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4375 poll_threads(); 4376 CU_ASSERT(g_bserrno == 0); 4377 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4378 4379 bs = g_bs; 4380 4381 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 4382 poll_threads(); 4383 CU_ASSERT(g_bserrno == 0); 4384 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4385 blob = g_blob; 4386 4387 CU_ASSERT(blob->active.clusters[1] != 0); 4388 4389 spdk_blob_close(blob, blob_op_complete, NULL); 4390 poll_threads(); 4391 CU_ASSERT(g_bserrno == 0); 4392 4393 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4394 poll_threads(); 4395 CU_ASSERT(g_bserrno == 0); 4396 4397 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4398 poll_threads(); 4399 CU_ASSERT(g_bserrno == 0); 4400 g_bs = NULL; 4401 } 4402 4403 static void 4404 blob_thin_prov_rw(void) 4405 { 4406 static const uint8_t zero[10 * 4096] = { 0 }; 4407 struct spdk_blob_store *bs; 4408 struct spdk_bs_dev *dev; 4409 struct spdk_blob *blob; 4410 struct spdk_io_channel *channel; 4411 struct spdk_blob_opts opts; 4412 spdk_blob_id blobid; 4413 uint64_t free_clusters; 4414 uint64_t page_size; 4415 uint8_t payload_read[10 * 4096]; 4416 uint8_t payload_write[10 * 4096]; 4417 uint64_t write_bytes; 4418 uint64_t read_bytes; 4419 4420 dev = init_dev(); 4421 4422 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4423 poll_threads(); 4424 CU_ASSERT(g_bserrno == 0); 4425 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4426 bs = g_bs; 4427 free_clusters = spdk_bs_free_cluster_count(bs); 4428 page_size = spdk_bs_get_page_size(bs); 4429 4430 channel = spdk_bs_alloc_io_channel(bs); 4431 CU_ASSERT(channel != NULL); 4432 4433 spdk_blob_opts_init(&opts); 4434 opts.thin_provision = true; 4435 4436 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4437 poll_threads(); 4438 CU_ASSERT(g_bserrno == 0); 4439 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4440 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4441 blobid = g_blobid; 4442 4443 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4444 poll_threads(); 4445 CU_ASSERT(g_bserrno == 0); 4446 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4447 blob = g_blob; 4448 4449 CU_ASSERT(blob->active.num_clusters == 0); 4450 4451 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4452 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4453 poll_threads(); 4454 CU_ASSERT(g_bserrno == 0); 4455 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4456 CU_ASSERT(blob->active.num_clusters == 5); 4457 4458 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4459 poll_threads(); 4460 CU_ASSERT(g_bserrno == 0); 4461 /* Sync must not change anything */ 4462 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4463 CU_ASSERT(blob->active.num_clusters == 5); 4464 4465 /* Payload should be all zeros from unallocated clusters */ 4466 memset(payload_read, 0xFF, sizeof(payload_read)); 4467 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4468 poll_threads(); 4469 CU_ASSERT(g_bserrno == 0); 4470 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4471 4472 write_bytes = g_dev_write_bytes; 4473 read_bytes = g_dev_read_bytes; 4474 4475 memset(payload_write, 0xE5, sizeof(payload_write)); 4476 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4477 poll_threads(); 4478 CU_ASSERT(g_bserrno == 0); 4479 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4480 /* For thin-provisioned blob we need to write 10 pages plus one page metadata and 4481 * read 0 bytes */ 4482 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11); 4483 CU_ASSERT(g_dev_read_bytes - read_bytes == 0); 4484 4485 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4486 poll_threads(); 4487 CU_ASSERT(g_bserrno == 0); 4488 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4489 4490 spdk_blob_close(blob, blob_op_complete, NULL); 4491 poll_threads(); 4492 CU_ASSERT(g_bserrno == 0); 4493 4494 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4495 poll_threads(); 4496 CU_ASSERT(g_bserrno == 0); 4497 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4498 4499 spdk_bs_free_io_channel(channel); 4500 poll_threads(); 4501 4502 /* Unload the blob store */ 4503 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4504 poll_threads(); 4505 CU_ASSERT(g_bserrno == 0); 4506 g_bs = NULL; 4507 g_blob = NULL; 4508 g_blobid = 0; 4509 } 4510 4511 static void 4512 blob_thin_prov_rw_iov(void) 4513 { 4514 static const uint8_t zero[10 * 4096] = { 0 }; 4515 struct spdk_blob_store *bs; 4516 struct spdk_bs_dev *dev; 4517 struct spdk_blob *blob; 4518 struct spdk_io_channel *channel; 4519 struct spdk_blob_opts opts; 4520 spdk_blob_id blobid; 4521 uint64_t free_clusters; 4522 uint8_t payload_read[10 * 4096]; 4523 uint8_t payload_write[10 * 4096]; 4524 struct iovec iov_read[3]; 4525 struct iovec iov_write[3]; 4526 4527 dev = init_dev(); 4528 4529 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4530 poll_threads(); 4531 CU_ASSERT(g_bserrno == 0); 4532 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4533 bs = g_bs; 4534 free_clusters = spdk_bs_free_cluster_count(bs); 4535 4536 channel = spdk_bs_alloc_io_channel(bs); 4537 CU_ASSERT(channel != NULL); 4538 4539 spdk_blob_opts_init(&opts); 4540 opts.thin_provision = true; 4541 4542 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4543 poll_threads(); 4544 CU_ASSERT(g_bserrno == 0); 4545 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4546 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4547 blobid = g_blobid; 4548 4549 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4550 poll_threads(); 4551 CU_ASSERT(g_bserrno == 0); 4552 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4553 blob = g_blob; 4554 4555 CU_ASSERT(blob->active.num_clusters == 0); 4556 4557 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4558 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4559 poll_threads(); 4560 CU_ASSERT(g_bserrno == 0); 4561 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4562 CU_ASSERT(blob->active.num_clusters == 5); 4563 4564 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4565 poll_threads(); 4566 CU_ASSERT(g_bserrno == 0); 4567 /* Sync must not change anything */ 4568 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4569 CU_ASSERT(blob->active.num_clusters == 5); 4570 4571 /* Payload should be all zeros from unallocated clusters */ 4572 memset(payload_read, 0xAA, sizeof(payload_read)); 4573 iov_read[0].iov_base = payload_read; 4574 iov_read[0].iov_len = 3 * 4096; 4575 iov_read[1].iov_base = payload_read + 3 * 4096; 4576 iov_read[1].iov_len = 4 * 4096; 4577 iov_read[2].iov_base = payload_read + 7 * 4096; 4578 iov_read[2].iov_len = 3 * 4096; 4579 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4580 poll_threads(); 4581 CU_ASSERT(g_bserrno == 0); 4582 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4583 4584 memset(payload_write, 0xE5, sizeof(payload_write)); 4585 iov_write[0].iov_base = payload_write; 4586 iov_write[0].iov_len = 1 * 4096; 4587 iov_write[1].iov_base = payload_write + 1 * 4096; 4588 iov_write[1].iov_len = 5 * 4096; 4589 iov_write[2].iov_base = payload_write + 6 * 4096; 4590 iov_write[2].iov_len = 4 * 4096; 4591 4592 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 4593 poll_threads(); 4594 CU_ASSERT(g_bserrno == 0); 4595 4596 memset(payload_read, 0xAA, sizeof(payload_read)); 4597 iov_read[0].iov_base = payload_read; 4598 iov_read[0].iov_len = 3 * 4096; 4599 iov_read[1].iov_base = payload_read + 3 * 4096; 4600 iov_read[1].iov_len = 4 * 4096; 4601 iov_read[2].iov_base = payload_read + 7 * 4096; 4602 iov_read[2].iov_len = 3 * 4096; 4603 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4604 poll_threads(); 4605 CU_ASSERT(g_bserrno == 0); 4606 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4607 4608 spdk_blob_close(blob, blob_op_complete, NULL); 4609 poll_threads(); 4610 CU_ASSERT(g_bserrno == 0); 4611 4612 spdk_bs_free_io_channel(channel); 4613 poll_threads(); 4614 4615 /* Unload the blob store */ 4616 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4617 poll_threads(); 4618 CU_ASSERT(g_bserrno == 0); 4619 g_bs = NULL; 4620 g_blob = NULL; 4621 g_blobid = 0; 4622 } 4623 4624 struct iter_ctx { 4625 int current_iter; 4626 spdk_blob_id blobid[4]; 4627 }; 4628 4629 static void 4630 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 4631 { 4632 struct iter_ctx *iter_ctx = arg; 4633 spdk_blob_id blobid; 4634 4635 CU_ASSERT(bserrno == 0); 4636 blobid = spdk_blob_get_id(blob); 4637 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 4638 } 4639 4640 static void 4641 bs_load_iter(void) 4642 { 4643 struct spdk_bs_dev *dev; 4644 struct iter_ctx iter_ctx = { 0 }; 4645 struct spdk_blob *blob; 4646 int i, rc; 4647 struct spdk_bs_opts opts; 4648 4649 dev = init_dev(); 4650 spdk_bs_opts_init(&opts); 4651 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4652 4653 /* Initialize a new blob store */ 4654 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 4655 poll_threads(); 4656 CU_ASSERT(g_bserrno == 0); 4657 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4658 4659 for (i = 0; i < 4; i++) { 4660 g_bserrno = -1; 4661 g_blobid = SPDK_BLOBID_INVALID; 4662 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 4663 poll_threads(); 4664 CU_ASSERT(g_bserrno == 0); 4665 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4666 iter_ctx.blobid[i] = g_blobid; 4667 4668 g_bserrno = -1; 4669 g_blob = NULL; 4670 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 4671 poll_threads(); 4672 CU_ASSERT(g_bserrno == 0); 4673 CU_ASSERT(g_blob != NULL); 4674 blob = g_blob; 4675 4676 /* Just save the blobid as an xattr for testing purposes. */ 4677 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 4678 CU_ASSERT(rc == 0); 4679 4680 /* Resize the blob */ 4681 spdk_blob_resize(blob, i, blob_op_complete, NULL); 4682 poll_threads(); 4683 CU_ASSERT(g_bserrno == 0); 4684 4685 spdk_blob_close(blob, blob_op_complete, NULL); 4686 poll_threads(); 4687 CU_ASSERT(g_bserrno == 0); 4688 } 4689 4690 g_bserrno = -1; 4691 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4692 poll_threads(); 4693 CU_ASSERT(g_bserrno == 0); 4694 4695 dev = init_dev(); 4696 spdk_bs_opts_init(&opts); 4697 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4698 opts.iter_cb_fn = test_iter; 4699 opts.iter_cb_arg = &iter_ctx; 4700 4701 /* Test blob iteration during load after a clean shutdown. */ 4702 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4703 poll_threads(); 4704 CU_ASSERT(g_bserrno == 0); 4705 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4706 4707 /* Dirty shutdown */ 4708 _spdk_bs_free(g_bs); 4709 4710 dev = init_dev(); 4711 spdk_bs_opts_init(&opts); 4712 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4713 opts.iter_cb_fn = test_iter; 4714 iter_ctx.current_iter = 0; 4715 opts.iter_cb_arg = &iter_ctx; 4716 4717 /* Test blob iteration during load after a dirty shutdown. */ 4718 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4719 poll_threads(); 4720 CU_ASSERT(g_bserrno == 0); 4721 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4722 4723 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4724 poll_threads(); 4725 CU_ASSERT(g_bserrno == 0); 4726 g_bs = NULL; 4727 } 4728 4729 static void 4730 blob_snapshot_rw(void) 4731 { 4732 static const uint8_t zero[10 * 4096] = { 0 }; 4733 struct spdk_blob_store *bs; 4734 struct spdk_bs_dev *dev; 4735 struct spdk_blob *blob, *snapshot; 4736 struct spdk_io_channel *channel; 4737 struct spdk_blob_opts opts; 4738 spdk_blob_id blobid, snapshotid; 4739 uint64_t free_clusters; 4740 uint64_t cluster_size; 4741 uint64_t page_size; 4742 uint8_t payload_read[10 * 4096]; 4743 uint8_t payload_write[10 * 4096]; 4744 uint64_t write_bytes; 4745 uint64_t read_bytes; 4746 4747 dev = init_dev(); 4748 4749 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4750 poll_threads(); 4751 CU_ASSERT(g_bserrno == 0); 4752 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4753 bs = g_bs; 4754 free_clusters = spdk_bs_free_cluster_count(bs); 4755 cluster_size = spdk_bs_get_cluster_size(bs); 4756 page_size = spdk_bs_get_page_size(bs); 4757 4758 channel = spdk_bs_alloc_io_channel(bs); 4759 CU_ASSERT(channel != NULL); 4760 4761 spdk_blob_opts_init(&opts); 4762 opts.thin_provision = true; 4763 opts.num_clusters = 5; 4764 4765 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4766 poll_threads(); 4767 CU_ASSERT(g_bserrno == 0); 4768 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4769 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4770 blobid = g_blobid; 4771 4772 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4773 poll_threads(); 4774 CU_ASSERT(g_bserrno == 0); 4775 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4776 blob = g_blob; 4777 4778 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4779 4780 memset(payload_read, 0xFF, sizeof(payload_read)); 4781 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4782 poll_threads(); 4783 CU_ASSERT(g_bserrno == 0); 4784 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4785 4786 memset(payload_write, 0xE5, sizeof(payload_write)); 4787 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4788 poll_threads(); 4789 CU_ASSERT(g_bserrno == 0); 4790 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4791 4792 /* Create snapshot from blob */ 4793 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4794 poll_threads(); 4795 CU_ASSERT(g_bserrno == 0); 4796 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4797 snapshotid = g_blobid; 4798 4799 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4800 poll_threads(); 4801 CU_ASSERT(g_bserrno == 0); 4802 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4803 snapshot = g_blob; 4804 CU_ASSERT(snapshot->data_ro == true) 4805 CU_ASSERT(snapshot->md_ro == true) 4806 4807 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 4808 4809 write_bytes = g_dev_write_bytes; 4810 read_bytes = g_dev_read_bytes; 4811 4812 memset(payload_write, 0xAA, sizeof(payload_write)); 4813 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4814 poll_threads(); 4815 CU_ASSERT(g_bserrno == 0); 4816 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4817 4818 /* For a clone we need to allocate and copy one cluster, update one page of metadata 4819 * and then write 10 pages of payload. 4820 */ 4821 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11 + cluster_size); 4822 CU_ASSERT(g_dev_read_bytes - read_bytes == cluster_size); 4823 4824 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4825 poll_threads(); 4826 CU_ASSERT(g_bserrno == 0); 4827 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4828 4829 /* Data on snapshot should not change after write to clone */ 4830 memset(payload_write, 0xE5, sizeof(payload_write)); 4831 spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL); 4832 poll_threads(); 4833 CU_ASSERT(g_bserrno == 0); 4834 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4835 4836 spdk_blob_close(blob, blob_op_complete, NULL); 4837 poll_threads(); 4838 CU_ASSERT(g_bserrno == 0); 4839 4840 spdk_blob_close(snapshot, blob_op_complete, NULL); 4841 poll_threads(); 4842 CU_ASSERT(g_bserrno == 0); 4843 4844 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4845 poll_threads(); 4846 CU_ASSERT(g_bserrno == 0); 4847 4848 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4849 poll_threads(); 4850 CU_ASSERT(g_bserrno == 0); 4851 4852 spdk_bs_free_io_channel(channel); 4853 poll_threads(); 4854 4855 /* Unload the blob store */ 4856 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4857 poll_threads(); 4858 CU_ASSERT(g_bserrno == 0); 4859 g_bs = NULL; 4860 g_blob = NULL; 4861 g_blobid = 0; 4862 } 4863 4864 static void 4865 blob_snapshot_rw_iov(void) 4866 { 4867 static const uint8_t zero[10 * 4096] = { 0 }; 4868 struct spdk_blob_store *bs; 4869 struct spdk_bs_dev *dev; 4870 struct spdk_blob *blob, *snapshot; 4871 struct spdk_io_channel *channel; 4872 struct spdk_blob_opts opts; 4873 spdk_blob_id blobid, snapshotid; 4874 uint64_t free_clusters; 4875 uint8_t payload_read[10 * 4096]; 4876 uint8_t payload_write[10 * 4096]; 4877 struct iovec iov_read[3]; 4878 struct iovec iov_write[3]; 4879 4880 dev = init_dev(); 4881 4882 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4883 poll_threads(); 4884 CU_ASSERT(g_bserrno == 0); 4885 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4886 bs = g_bs; 4887 free_clusters = spdk_bs_free_cluster_count(bs); 4888 4889 channel = spdk_bs_alloc_io_channel(bs); 4890 CU_ASSERT(channel != NULL); 4891 4892 spdk_blob_opts_init(&opts); 4893 opts.thin_provision = true; 4894 opts.num_clusters = 5; 4895 4896 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4897 poll_threads(); 4898 CU_ASSERT(g_bserrno == 0); 4899 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4900 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4901 blobid = g_blobid; 4902 4903 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4904 poll_threads(); 4905 CU_ASSERT(g_bserrno == 0); 4906 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4907 blob = g_blob; 4908 4909 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4910 4911 /* Create snapshot from blob */ 4912 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4913 poll_threads(); 4914 CU_ASSERT(g_bserrno == 0); 4915 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4916 snapshotid = g_blobid; 4917 4918 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4919 poll_threads(); 4920 CU_ASSERT(g_bserrno == 0); 4921 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4922 snapshot = g_blob; 4923 CU_ASSERT(snapshot->data_ro == true) 4924 CU_ASSERT(snapshot->md_ro == true) 4925 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 4926 4927 /* Payload should be all zeros from unallocated clusters */ 4928 memset(payload_read, 0xAA, sizeof(payload_read)); 4929 iov_read[0].iov_base = payload_read; 4930 iov_read[0].iov_len = 3 * 4096; 4931 iov_read[1].iov_base = payload_read + 3 * 4096; 4932 iov_read[1].iov_len = 4 * 4096; 4933 iov_read[2].iov_base = payload_read + 7 * 4096; 4934 iov_read[2].iov_len = 3 * 4096; 4935 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4936 poll_threads(); 4937 CU_ASSERT(g_bserrno == 0); 4938 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4939 4940 memset(payload_write, 0xE5, sizeof(payload_write)); 4941 iov_write[0].iov_base = payload_write; 4942 iov_write[0].iov_len = 1 * 4096; 4943 iov_write[1].iov_base = payload_write + 1 * 4096; 4944 iov_write[1].iov_len = 5 * 4096; 4945 iov_write[2].iov_base = payload_write + 6 * 4096; 4946 iov_write[2].iov_len = 4 * 4096; 4947 4948 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 4949 poll_threads(); 4950 CU_ASSERT(g_bserrno == 0); 4951 4952 memset(payload_read, 0xAA, sizeof(payload_read)); 4953 iov_read[0].iov_base = payload_read; 4954 iov_read[0].iov_len = 3 * 4096; 4955 iov_read[1].iov_base = payload_read + 3 * 4096; 4956 iov_read[1].iov_len = 4 * 4096; 4957 iov_read[2].iov_base = payload_read + 7 * 4096; 4958 iov_read[2].iov_len = 3 * 4096; 4959 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4960 poll_threads(); 4961 CU_ASSERT(g_bserrno == 0); 4962 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4963 4964 spdk_blob_close(blob, blob_op_complete, NULL); 4965 poll_threads(); 4966 CU_ASSERT(g_bserrno == 0); 4967 4968 spdk_blob_close(snapshot, blob_op_complete, NULL); 4969 poll_threads(); 4970 CU_ASSERT(g_bserrno == 0); 4971 4972 spdk_bs_free_io_channel(channel); 4973 poll_threads(); 4974 4975 /* Unload the blob store */ 4976 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4977 poll_threads(); 4978 CU_ASSERT(g_bserrno == 0); 4979 g_bs = NULL; 4980 g_blob = NULL; 4981 g_blobid = 0; 4982 } 4983 4984 /** 4985 * Inflate / decouple parent rw unit tests. 4986 * 4987 * -------------- 4988 * original blob: 0 1 2 3 4 4989 * ,---------+---------+---------+---------+---------. 4990 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 4991 * +---------+---------+---------+---------+---------+ 4992 * snapshot2 | - |yyyyyyyyy| - |yyyyyyyyy| - | 4993 * +---------+---------+---------+---------+---------+ 4994 * blob | - |zzzzzzzzz| - | - | - | 4995 * '---------+---------+---------+---------+---------' 4996 * . . . . . . 4997 * -------- . . . . . . 4998 * inflate: . . . . . . 4999 * ,---------+---------+---------+---------+---------. 5000 * blob |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000| 5001 * '---------+---------+---------+---------+---------' 5002 * 5003 * NOTE: needs to allocate 4 clusters, thin provisioning removed, dependency 5004 * on snapshot2 and snapshot removed . . . 5005 * . . . . . . 5006 * ---------------- . . . . . . 5007 * decouple parent: . . . . . . 5008 * ,---------+---------+---------+---------+---------. 5009 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 5010 * +---------+---------+---------+---------+---------+ 5011 * blob | - |zzzzzzzzz| - |yyyyyyyyy| - | 5012 * '---------+---------+---------+---------+---------' 5013 * 5014 * NOTE: needs to allocate 1 cluster, 3 clusters unallocated, dependency 5015 * on snapshot2 removed and on snapshot still exists. Snapshot2 5016 * should remain a clone of snapshot. 5017 */ 5018 static void 5019 _blob_inflate_rw(bool decouple_parent) 5020 { 5021 struct spdk_blob_store *bs; 5022 struct spdk_bs_dev *dev; 5023 struct spdk_blob *blob, *snapshot, *snapshot2; 5024 struct spdk_io_channel *channel; 5025 struct spdk_blob_opts opts; 5026 spdk_blob_id blobid, snapshotid, snapshot2id; 5027 uint64_t free_clusters; 5028 uint64_t cluster_size; 5029 5030 uint64_t payload_size; 5031 uint8_t *payload_read; 5032 uint8_t *payload_write; 5033 uint8_t *payload_clone; 5034 5035 uint64_t pages_per_cluster; 5036 uint64_t pages_per_payload; 5037 5038 int i; 5039 spdk_blob_id ids[2]; 5040 size_t count; 5041 5042 dev = init_dev(); 5043 5044 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5045 poll_threads(); 5046 CU_ASSERT(g_bserrno == 0); 5047 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5048 bs = g_bs; 5049 5050 free_clusters = spdk_bs_free_cluster_count(bs); 5051 cluster_size = spdk_bs_get_cluster_size(bs); 5052 pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs); 5053 pages_per_payload = pages_per_cluster * 5; 5054 5055 payload_size = cluster_size * 5; 5056 5057 payload_read = malloc(payload_size); 5058 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 5059 5060 payload_write = malloc(payload_size); 5061 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 5062 5063 payload_clone = malloc(payload_size); 5064 SPDK_CU_ASSERT_FATAL(payload_clone != NULL); 5065 5066 channel = spdk_bs_alloc_io_channel(bs); 5067 SPDK_CU_ASSERT_FATAL(channel != NULL); 5068 5069 /* Create blob */ 5070 spdk_blob_opts_init(&opts); 5071 opts.thin_provision = true; 5072 opts.num_clusters = 5; 5073 5074 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5075 poll_threads(); 5076 CU_ASSERT(g_bserrno == 0); 5077 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5078 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5079 blobid = g_blobid; 5080 5081 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5082 poll_threads(); 5083 CU_ASSERT(g_bserrno == 0); 5084 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5085 blob = g_blob; 5086 5087 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5088 5089 /* 1) Initial read should return zeroed payload */ 5090 memset(payload_read, 0xFF, payload_size); 5091 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5092 blob_op_complete, NULL); 5093 poll_threads(); 5094 CU_ASSERT(g_bserrno == 0); 5095 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 5096 5097 /* Fill whole blob with a pattern, except last cluster (to be sure it 5098 * isn't allocated) */ 5099 memset(payload_write, 0xE5, payload_size - cluster_size); 5100 spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload - 5101 pages_per_cluster, blob_op_complete, NULL); 5102 poll_threads(); 5103 CU_ASSERT(g_bserrno == 0); 5104 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5105 5106 /* 2) Create snapshot from blob (first level) */ 5107 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5108 poll_threads(); 5109 CU_ASSERT(g_bserrno == 0); 5110 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5111 snapshotid = g_blobid; 5112 5113 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5114 poll_threads(); 5115 CU_ASSERT(g_bserrno == 0); 5116 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5117 snapshot = g_blob; 5118 CU_ASSERT(snapshot->data_ro == true) 5119 CU_ASSERT(snapshot->md_ro == true) 5120 5121 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 5122 5123 /* Write every second cluster with a pattern. 5124 * 5125 * Last cluster shouldn't be written, to be sure that snapshot nor clone 5126 * doesn't allocate it. 5127 * 5128 * payload_clone stores expected result on "blob" read at the time and 5129 * is used only to check data consistency on clone before and after 5130 * inflation. Initially we fill it with a backing snapshots pattern 5131 * used before. 5132 */ 5133 memset(payload_clone, 0xE5, payload_size - cluster_size); 5134 memset(payload_clone + payload_size - cluster_size, 0x00, cluster_size); 5135 memset(payload_write, 0xAA, payload_size); 5136 for (i = 1; i < 5; i += 2) { 5137 spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster, 5138 pages_per_cluster, blob_op_complete, NULL); 5139 poll_threads(); 5140 CU_ASSERT(g_bserrno == 0); 5141 5142 /* Update expected result */ 5143 memcpy(payload_clone + (cluster_size * i), payload_write, 5144 cluster_size); 5145 } 5146 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5147 5148 /* Check data consistency on clone */ 5149 memset(payload_read, 0xFF, payload_size); 5150 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5151 blob_op_complete, NULL); 5152 poll_threads(); 5153 CU_ASSERT(g_bserrno == 0); 5154 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5155 5156 /* 3) Create second levels snapshot from blob */ 5157 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5158 poll_threads(); 5159 CU_ASSERT(g_bserrno == 0); 5160 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5161 snapshot2id = g_blobid; 5162 5163 spdk_bs_open_blob(bs, snapshot2id, blob_op_with_handle_complete, NULL); 5164 poll_threads(); 5165 CU_ASSERT(g_bserrno == 0); 5166 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5167 snapshot2 = g_blob; 5168 CU_ASSERT(snapshot2->data_ro == true) 5169 CU_ASSERT(snapshot2->md_ro == true) 5170 5171 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 5) 5172 5173 CU_ASSERT(snapshot2->parent_id == snapshotid); 5174 5175 /* Write one cluster on the top level blob. This cluster (1) covers 5176 * already allocated cluster in the snapshot2, so shouldn't be inflated 5177 * at all */ 5178 spdk_blob_io_write(blob, channel, payload_write, pages_per_cluster, 5179 pages_per_cluster, blob_op_complete, NULL); 5180 poll_threads(); 5181 CU_ASSERT(g_bserrno == 0); 5182 5183 /* Update expected result */ 5184 memcpy(payload_clone + cluster_size, payload_write, cluster_size); 5185 5186 /* Check data consistency on clone */ 5187 memset(payload_read, 0xFF, payload_size); 5188 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5189 blob_op_complete, NULL); 5190 poll_threads(); 5191 CU_ASSERT(g_bserrno == 0); 5192 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5193 5194 5195 /* Close all blobs */ 5196 spdk_blob_close(blob, blob_op_complete, NULL); 5197 poll_threads(); 5198 CU_ASSERT(g_bserrno == 0); 5199 5200 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5201 poll_threads(); 5202 CU_ASSERT(g_bserrno == 0); 5203 5204 spdk_blob_close(snapshot, blob_op_complete, NULL); 5205 poll_threads(); 5206 CU_ASSERT(g_bserrno == 0); 5207 5208 /* Check snapshot-clone relations */ 5209 count = 2; 5210 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5211 CU_ASSERT(count == 1); 5212 CU_ASSERT(ids[0] == snapshot2id); 5213 5214 count = 2; 5215 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5216 CU_ASSERT(count == 1); 5217 CU_ASSERT(ids[0] == blobid); 5218 5219 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshot2id); 5220 5221 free_clusters = spdk_bs_free_cluster_count(bs); 5222 if (!decouple_parent) { 5223 /* Do full blob inflation */ 5224 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 5225 poll_threads(); 5226 CU_ASSERT(g_bserrno == 0); 5227 5228 /* All clusters should be inflated (except one already allocated 5229 * in a top level blob) */ 5230 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 4); 5231 5232 /* Check if relation tree updated correctly */ 5233 count = 2; 5234 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5235 5236 /* snapshotid have one clone */ 5237 CU_ASSERT(count == 1); 5238 CU_ASSERT(ids[0] == snapshot2id); 5239 5240 /* snapshot2id have no clones */ 5241 count = 2; 5242 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5243 CU_ASSERT(count == 0); 5244 5245 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5246 } else { 5247 /* Decouple parent of blob */ 5248 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 5249 poll_threads(); 5250 CU_ASSERT(g_bserrno == 0); 5251 5252 /* Only one cluster from a parent should be inflated (second one 5253 * is covered by a cluster written on a top level blob, and 5254 * already allocated) */ 5255 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 1); 5256 5257 /* Check if relation tree updated correctly */ 5258 count = 2; 5259 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5260 5261 /* snapshotid have two clones now */ 5262 CU_ASSERT(count == 2); 5263 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5264 CU_ASSERT(ids[0] == snapshot2id || ids[1] == snapshot2id); 5265 5266 /* snapshot2id have no clones */ 5267 count = 2; 5268 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5269 CU_ASSERT(count == 0); 5270 5271 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5272 } 5273 5274 /* Try to delete snapshot2 (should pass) */ 5275 spdk_bs_delete_blob(bs, snapshot2id, blob_op_complete, NULL); 5276 poll_threads(); 5277 CU_ASSERT(g_bserrno == 0); 5278 5279 /* Try to delete base snapshot (for decouple_parent should fail while 5280 * dependency still exists) */ 5281 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5282 poll_threads(); 5283 CU_ASSERT(decouple_parent || g_bserrno == 0); 5284 CU_ASSERT(!decouple_parent || g_bserrno != 0); 5285 5286 /* Reopen blob after snapshot deletion */ 5287 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5288 poll_threads(); 5289 CU_ASSERT(g_bserrno == 0); 5290 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5291 blob = g_blob; 5292 5293 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5294 5295 /* Check data consistency on inflated blob */ 5296 memset(payload_read, 0xFF, payload_size); 5297 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5298 blob_op_complete, NULL); 5299 poll_threads(); 5300 CU_ASSERT(g_bserrno == 0); 5301 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5302 5303 spdk_blob_close(blob, blob_op_complete, NULL); 5304 poll_threads(); 5305 CU_ASSERT(g_bserrno == 0); 5306 5307 spdk_bs_free_io_channel(channel); 5308 poll_threads(); 5309 5310 /* Unload the blob store */ 5311 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5312 poll_threads(); 5313 CU_ASSERT(g_bserrno == 0); 5314 g_bs = NULL; 5315 g_blob = NULL; 5316 g_blobid = 0; 5317 5318 free(payload_read); 5319 free(payload_write); 5320 free(payload_clone); 5321 } 5322 5323 static void 5324 blob_inflate_rw(void) 5325 { 5326 _blob_inflate_rw(false); 5327 _blob_inflate_rw(true); 5328 } 5329 5330 /** 5331 * Snapshot-clones relation test 5332 * 5333 * snapshot 5334 * | 5335 * +-----+-----+ 5336 * | | 5337 * blob(ro) snapshot2 5338 * | | 5339 * clone2 clone 5340 */ 5341 static void 5342 blob_relations(void) 5343 { 5344 struct spdk_blob_store *bs; 5345 struct spdk_bs_dev *dev; 5346 struct spdk_bs_opts bs_opts; 5347 struct spdk_blob_opts opts; 5348 struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2; 5349 spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2; 5350 int rc; 5351 size_t count; 5352 spdk_blob_id ids[10] = {}; 5353 5354 dev = init_dev(); 5355 spdk_bs_opts_init(&bs_opts); 5356 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5357 5358 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 5359 poll_threads(); 5360 CU_ASSERT(g_bserrno == 0); 5361 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5362 bs = g_bs; 5363 5364 /* 1. Create blob with 10 clusters */ 5365 5366 spdk_blob_opts_init(&opts); 5367 opts.num_clusters = 10; 5368 5369 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5370 poll_threads(); 5371 CU_ASSERT(g_bserrno == 0); 5372 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5373 blobid = g_blobid; 5374 5375 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5376 poll_threads(); 5377 CU_ASSERT(g_bserrno == 0); 5378 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5379 blob = g_blob; 5380 5381 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5382 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5383 CU_ASSERT(!spdk_blob_is_clone(blob)); 5384 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob)); 5385 5386 /* blob should not have underlying snapshot nor clones */ 5387 CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID); 5388 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5389 count = SPDK_COUNTOF(ids); 5390 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5391 CU_ASSERT(rc == 0); 5392 CU_ASSERT(count == 0); 5393 5394 5395 /* 2. Create snapshot */ 5396 5397 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5398 poll_threads(); 5399 CU_ASSERT(g_bserrno == 0); 5400 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5401 snapshotid = g_blobid; 5402 5403 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5404 poll_threads(); 5405 CU_ASSERT(g_bserrno == 0); 5406 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5407 snapshot = g_blob; 5408 5409 CU_ASSERT(spdk_blob_is_read_only(snapshot)); 5410 CU_ASSERT(spdk_blob_is_snapshot(snapshot)); 5411 CU_ASSERT(!spdk_blob_is_clone(snapshot)); 5412 CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID); 5413 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5414 5415 /* Check if original blob is converted to the clone of snapshot */ 5416 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5417 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5418 CU_ASSERT(spdk_blob_is_clone(blob)); 5419 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5420 CU_ASSERT(blob->parent_id == snapshotid); 5421 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5422 5423 count = SPDK_COUNTOF(ids); 5424 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5425 CU_ASSERT(rc == 0); 5426 CU_ASSERT(count == 1); 5427 CU_ASSERT(ids[0] == blobid); 5428 5429 5430 /* 3. Create clone from snapshot */ 5431 5432 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 5433 poll_threads(); 5434 CU_ASSERT(g_bserrno == 0); 5435 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5436 cloneid = g_blobid; 5437 5438 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 5439 poll_threads(); 5440 CU_ASSERT(g_bserrno == 0); 5441 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5442 clone = g_blob; 5443 5444 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5445 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5446 CU_ASSERT(spdk_blob_is_clone(clone)); 5447 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5448 CU_ASSERT(clone->parent_id == snapshotid); 5449 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 5450 5451 count = SPDK_COUNTOF(ids); 5452 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5453 CU_ASSERT(rc == 0); 5454 CU_ASSERT(count == 0); 5455 5456 /* Check if clone is on the snapshot's list */ 5457 count = SPDK_COUNTOF(ids); 5458 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5459 CU_ASSERT(rc == 0); 5460 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5461 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 5462 5463 5464 /* 4. Create snapshot of the clone */ 5465 5466 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 5467 poll_threads(); 5468 CU_ASSERT(g_bserrno == 0); 5469 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5470 snapshotid2 = g_blobid; 5471 5472 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 5473 poll_threads(); 5474 CU_ASSERT(g_bserrno == 0); 5475 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5476 snapshot2 = g_blob; 5477 5478 CU_ASSERT(spdk_blob_is_read_only(snapshot2)); 5479 CU_ASSERT(spdk_blob_is_snapshot(snapshot2)); 5480 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 5481 CU_ASSERT(snapshot2->parent_id == snapshotid); 5482 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5483 5484 /* Check if clone is converted to the clone of snapshot2 and snapshot2 5485 * is a child of snapshot */ 5486 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5487 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5488 CU_ASSERT(spdk_blob_is_clone(clone)); 5489 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5490 CU_ASSERT(clone->parent_id == snapshotid2); 5491 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5492 5493 count = SPDK_COUNTOF(ids); 5494 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5495 CU_ASSERT(rc == 0); 5496 CU_ASSERT(count == 1); 5497 CU_ASSERT(ids[0] == cloneid); 5498 5499 5500 /* 5. Try to create clone from read only blob */ 5501 5502 /* Mark blob as read only */ 5503 spdk_blob_set_read_only(blob); 5504 spdk_blob_sync_md(blob, blob_op_complete, NULL); 5505 poll_threads(); 5506 CU_ASSERT(g_bserrno == 0); 5507 5508 /* Check if previously created blob is read only clone */ 5509 CU_ASSERT(spdk_blob_is_read_only(blob)); 5510 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5511 CU_ASSERT(spdk_blob_is_clone(blob)); 5512 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5513 5514 /* Create clone from read only blob */ 5515 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5516 poll_threads(); 5517 CU_ASSERT(g_bserrno == 0); 5518 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5519 cloneid2 = g_blobid; 5520 5521 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 5522 poll_threads(); 5523 CU_ASSERT(g_bserrno == 0); 5524 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5525 clone2 = g_blob; 5526 5527 CU_ASSERT(!spdk_blob_is_read_only(clone2)); 5528 CU_ASSERT(!spdk_blob_is_snapshot(clone2)); 5529 CU_ASSERT(spdk_blob_is_clone(clone2)); 5530 CU_ASSERT(spdk_blob_is_thin_provisioned(clone2)); 5531 5532 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5533 5534 count = SPDK_COUNTOF(ids); 5535 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5536 CU_ASSERT(rc == 0); 5537 5538 CU_ASSERT(count == 1); 5539 CU_ASSERT(ids[0] == cloneid2); 5540 5541 /* Close blobs */ 5542 5543 spdk_blob_close(clone2, blob_op_complete, NULL); 5544 poll_threads(); 5545 CU_ASSERT(g_bserrno == 0); 5546 5547 spdk_blob_close(blob, blob_op_complete, NULL); 5548 poll_threads(); 5549 CU_ASSERT(g_bserrno == 0); 5550 5551 spdk_blob_close(clone, blob_op_complete, NULL); 5552 poll_threads(); 5553 CU_ASSERT(g_bserrno == 0); 5554 5555 spdk_blob_close(snapshot, blob_op_complete, NULL); 5556 poll_threads(); 5557 CU_ASSERT(g_bserrno == 0); 5558 5559 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5560 poll_threads(); 5561 CU_ASSERT(g_bserrno == 0); 5562 5563 /* Try to delete snapshot with created clones */ 5564 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5565 poll_threads(); 5566 CU_ASSERT(g_bserrno != 0); 5567 5568 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5569 poll_threads(); 5570 CU_ASSERT(g_bserrno != 0); 5571 5572 spdk_bs_unload(bs, bs_op_complete, NULL); 5573 poll_threads(); 5574 CU_ASSERT(g_bserrno == 0); 5575 g_bs = NULL; 5576 5577 /* Load an existing blob store */ 5578 dev = init_dev(); 5579 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5580 5581 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 5582 poll_threads(); 5583 CU_ASSERT(g_bserrno == 0); 5584 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5585 bs = g_bs; 5586 5587 5588 /* NULL ids array should return number of clones in count */ 5589 count = SPDK_COUNTOF(ids); 5590 rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count); 5591 CU_ASSERT(rc == -ENOMEM); 5592 CU_ASSERT(count == 2); 5593 5594 /* incorrect array size */ 5595 count = 1; 5596 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5597 CU_ASSERT(rc == -ENOMEM); 5598 CU_ASSERT(count == 2); 5599 5600 5601 /* Verify structure of loaded blob store */ 5602 5603 /* snapshot */ 5604 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5605 5606 count = SPDK_COUNTOF(ids); 5607 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5608 CU_ASSERT(rc == 0); 5609 CU_ASSERT(count == 2); 5610 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5611 CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2); 5612 5613 /* blob */ 5614 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5615 count = SPDK_COUNTOF(ids); 5616 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5617 CU_ASSERT(rc == 0); 5618 CU_ASSERT(count == 1); 5619 CU_ASSERT(ids[0] == cloneid2); 5620 5621 /* clone */ 5622 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5623 count = SPDK_COUNTOF(ids); 5624 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5625 CU_ASSERT(rc == 0); 5626 CU_ASSERT(count == 0); 5627 5628 /* snapshot2 */ 5629 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5630 count = SPDK_COUNTOF(ids); 5631 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5632 CU_ASSERT(rc == 0); 5633 CU_ASSERT(count == 1); 5634 CU_ASSERT(ids[0] == cloneid); 5635 5636 /* clone2 */ 5637 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5638 count = SPDK_COUNTOF(ids); 5639 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 5640 CU_ASSERT(rc == 0); 5641 CU_ASSERT(count == 0); 5642 5643 /* Try to delete all blobs in the worse possible order */ 5644 5645 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5646 poll_threads(); 5647 CU_ASSERT(g_bserrno != 0); 5648 5649 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5650 poll_threads(); 5651 CU_ASSERT(g_bserrno != 0); 5652 5653 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 5654 poll_threads(); 5655 CU_ASSERT(g_bserrno == 0); 5656 5657 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5658 poll_threads(); 5659 CU_ASSERT(g_bserrno == 0); 5660 5661 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5662 poll_threads(); 5663 CU_ASSERT(g_bserrno != 0); 5664 5665 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5666 poll_threads(); 5667 CU_ASSERT(g_bserrno != 0); 5668 5669 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 5670 poll_threads(); 5671 CU_ASSERT(g_bserrno == 0); 5672 5673 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5674 poll_threads(); 5675 CU_ASSERT(g_bserrno == 0); 5676 5677 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5678 poll_threads(); 5679 CU_ASSERT(g_bserrno == 0); 5680 5681 spdk_bs_unload(bs, bs_op_complete, NULL); 5682 poll_threads(); 5683 CU_ASSERT(g_bserrno == 0); 5684 5685 g_bs = NULL; 5686 } 5687 5688 static void 5689 test_io_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5690 { 5691 uint8_t payload_ff[64 * 512]; 5692 uint8_t payload_aa[64 * 512]; 5693 uint8_t payload_00[64 * 512]; 5694 uint8_t *cluster0, *cluster1; 5695 5696 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5697 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5698 memset(payload_00, 0x00, sizeof(payload_00)); 5699 5700 /* Try to perform I/O with io unit = 512 */ 5701 spdk_blob_io_write(blob, channel, payload_ff, 0, 1, blob_op_complete, NULL); 5702 poll_threads(); 5703 CU_ASSERT(g_bserrno == 0); 5704 5705 /* If thin provisioned is set cluster should be allocated now */ 5706 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 5707 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 5708 5709 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 5710 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 5711 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5712 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5713 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 5714 5715 /* Verify write with offset on first page */ 5716 spdk_blob_io_write(blob, channel, payload_ff, 2, 1, blob_op_complete, NULL); 5717 poll_threads(); 5718 CU_ASSERT(g_bserrno == 0); 5719 5720 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5721 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5722 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5723 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5724 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5725 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 5726 5727 /* Verify write with offset on first page */ 5728 spdk_blob_io_write(blob, channel, payload_ff, 4, 4, blob_op_complete, NULL); 5729 poll_threads(); 5730 5731 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5732 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5733 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5734 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5735 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5736 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 5737 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 5738 5739 /* Verify write with offset on second page */ 5740 spdk_blob_io_write(blob, channel, payload_ff, 8, 4, blob_op_complete, NULL); 5741 poll_threads(); 5742 5743 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 5744 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5745 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5746 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5747 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5748 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 5749 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 5750 5751 /* Verify write across multiple pages */ 5752 spdk_blob_io_write(blob, channel, payload_aa, 4, 8, blob_op_complete, NULL); 5753 poll_threads(); 5754 5755 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 5756 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5757 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5758 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5759 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5760 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 5761 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 5762 5763 /* Verify write across multiple clusters */ 5764 spdk_blob_io_write(blob, channel, payload_ff, 28, 8, blob_op_complete, NULL); 5765 poll_threads(); 5766 5767 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 5768 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5769 5770 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5771 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5772 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5773 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5774 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5775 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5776 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 5777 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 5778 5779 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 5780 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 5781 5782 /* Verify write to second cluster */ 5783 spdk_blob_io_write(blob, channel, payload_ff, 32 + 12, 2, blob_op_complete, NULL); 5784 poll_threads(); 5785 5786 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 5787 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5788 5789 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5790 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 5791 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5792 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5793 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5794 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5795 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 5796 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 5797 5798 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 5799 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 5800 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 5801 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 5802 } 5803 5804 static void 5805 test_io_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5806 { 5807 uint8_t payload_read[64 * 512]; 5808 uint8_t payload_ff[64 * 512]; 5809 uint8_t payload_aa[64 * 512]; 5810 uint8_t payload_00[64 * 512]; 5811 5812 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5813 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5814 memset(payload_00, 0x00, sizeof(payload_00)); 5815 5816 /* Read only first io unit */ 5817 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5818 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5819 * payload_read: F000 0000 | 0000 0000 ... */ 5820 memset(payload_read, 0x00, sizeof(payload_read)); 5821 spdk_blob_io_read(blob, channel, payload_read, 0, 1, blob_op_complete, NULL); 5822 poll_threads(); 5823 CU_ASSERT(g_bserrno == 0); 5824 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 5825 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 5826 5827 /* Read four io_units starting from offset = 2 5828 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5829 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5830 * payload_read: F0AA 0000 | 0000 0000 ... */ 5831 5832 memset(payload_read, 0x00, sizeof(payload_read)); 5833 spdk_blob_io_read(blob, channel, payload_read, 2, 4, blob_op_complete, NULL); 5834 poll_threads(); 5835 CU_ASSERT(g_bserrno == 0); 5836 5837 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 5838 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 5839 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 5840 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 5841 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 5842 5843 /* Read eight io_units across multiple pages 5844 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 5845 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5846 * payload_read: AAAA AAAA | 0000 0000 ... */ 5847 memset(payload_read, 0x00, sizeof(payload_read)); 5848 spdk_blob_io_read(blob, channel, payload_read, 4, 8, blob_op_complete, NULL); 5849 poll_threads(); 5850 CU_ASSERT(g_bserrno == 0); 5851 5852 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 5853 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 5854 5855 /* Read eight io_units across multiple clusters 5856 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 5857 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5858 * payload_read: FFFF FFFF | 0000 0000 ... */ 5859 memset(payload_read, 0x00, sizeof(payload_read)); 5860 spdk_blob_io_read(blob, channel, payload_read, 28, 8, blob_op_complete, NULL); 5861 poll_threads(); 5862 CU_ASSERT(g_bserrno == 0); 5863 5864 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 5865 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 5866 5867 /* Read four io_units from second cluster 5868 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5869 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 5870 * payload_read: 00FF 0000 | 0000 0000 ... */ 5871 memset(payload_read, 0x00, sizeof(payload_read)); 5872 spdk_blob_io_read(blob, channel, payload_read, 32 + 10, 4, blob_op_complete, NULL); 5873 poll_threads(); 5874 CU_ASSERT(g_bserrno == 0); 5875 5876 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 5877 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 5878 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 5879 5880 /* Read second cluster 5881 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5882 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 5883 * payload_read: FFFF 0000 | 0000 FF00 ... */ 5884 memset(payload_read, 0x00, sizeof(payload_read)); 5885 spdk_blob_io_read(blob, channel, payload_read, 32, 32, blob_op_complete, NULL); 5886 poll_threads(); 5887 CU_ASSERT(g_bserrno == 0); 5888 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 5889 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 5890 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 5891 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 5892 5893 /* Read whole two clusters 5894 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 5895 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 5896 memset(payload_read, 0x00, sizeof(payload_read)); 5897 spdk_blob_io_read(blob, channel, payload_read, 0, 64, blob_op_complete, NULL); 5898 poll_threads(); 5899 CU_ASSERT(g_bserrno == 0); 5900 5901 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 5902 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 5903 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 5904 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 5905 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 5906 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 5907 5908 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 5909 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 5910 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 5911 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 5912 } 5913 5914 5915 static void 5916 test_io_unmap(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5917 { 5918 uint8_t payload_ff[64 * 512]; 5919 uint8_t payload_aa[64 * 512]; 5920 uint8_t payload_00[64 * 512]; 5921 uint8_t *cluster0, *cluster1; 5922 5923 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5924 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5925 memset(payload_00, 0x00, sizeof(payload_00)); 5926 5927 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 5928 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5929 5930 /* Unmap */ 5931 spdk_blob_io_unmap(blob, channel, 0, 64, blob_op_complete, NULL); 5932 poll_threads(); 5933 5934 CU_ASSERT(g_bserrno == 0); 5935 5936 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 5937 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 5938 } 5939 5940 static void 5941 test_io_zeroes(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5942 { 5943 uint8_t payload_ff[64 * 512]; 5944 uint8_t payload_aa[64 * 512]; 5945 uint8_t payload_00[64 * 512]; 5946 uint8_t *cluster0, *cluster1; 5947 5948 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5949 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5950 memset(payload_00, 0x00, sizeof(payload_00)); 5951 5952 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 5953 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5954 5955 /* Write zeroes */ 5956 spdk_blob_io_write_zeroes(blob, channel, 0, 64, blob_op_complete, NULL); 5957 poll_threads(); 5958 5959 CU_ASSERT(g_bserrno == 0); 5960 5961 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 5962 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 5963 } 5964 5965 5966 static void 5967 test_iov_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5968 { 5969 uint8_t payload_ff[64 * 512]; 5970 uint8_t payload_aa[64 * 512]; 5971 uint8_t payload_00[64 * 512]; 5972 uint8_t *cluster0, *cluster1; 5973 struct iovec iov[4]; 5974 5975 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5976 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5977 memset(payload_00, 0x00, sizeof(payload_00)); 5978 5979 /* Try to perform I/O with io unit = 512 */ 5980 iov[0].iov_base = payload_ff; 5981 iov[0].iov_len = 1 * 512; 5982 spdk_blob_io_writev(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 5983 poll_threads(); 5984 CU_ASSERT(g_bserrno == 0); 5985 5986 /* If thin provisioned is set cluster should be allocated now */ 5987 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 5988 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 5989 5990 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 5991 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 5992 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5993 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5994 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 5995 5996 /* Verify write with offset on first page */ 5997 iov[0].iov_base = payload_ff; 5998 iov[0].iov_len = 1 * 512; 5999 spdk_blob_io_writev(blob, channel, iov, 1, 2, 1, blob_op_complete, NULL); 6000 poll_threads(); 6001 CU_ASSERT(g_bserrno == 0); 6002 6003 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6004 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6005 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6006 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6007 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6008 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 6009 6010 /* Verify write with offset on first page */ 6011 iov[0].iov_base = payload_ff; 6012 iov[0].iov_len = 4 * 512; 6013 spdk_blob_io_writev(blob, channel, iov, 1, 4, 4, blob_op_complete, NULL); 6014 poll_threads(); 6015 6016 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6017 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6018 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6019 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6020 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6021 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 6022 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 6023 6024 /* Verify write with offset on second page */ 6025 iov[0].iov_base = payload_ff; 6026 iov[0].iov_len = 4 * 512; 6027 spdk_blob_io_writev(blob, channel, iov, 1, 8, 4, blob_op_complete, NULL); 6028 poll_threads(); 6029 6030 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 6031 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6032 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6033 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6034 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6035 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 6036 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6037 6038 /* Verify write across multiple pages */ 6039 iov[0].iov_base = payload_aa; 6040 iov[0].iov_len = 8 * 512; 6041 spdk_blob_io_writev(blob, channel, iov, 1, 4, 8, blob_op_complete, NULL); 6042 poll_threads(); 6043 6044 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 6045 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6046 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6047 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6048 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6049 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6050 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6051 6052 /* Verify write across multiple clusters */ 6053 6054 iov[0].iov_base = payload_ff; 6055 iov[0].iov_len = 8 * 512; 6056 spdk_blob_io_writev(blob, channel, iov, 1, 28, 8, blob_op_complete, NULL); 6057 poll_threads(); 6058 6059 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6060 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6061 6062 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6063 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6064 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6065 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6066 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6067 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6068 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6069 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 16 * 512) == 0); 6070 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6071 6072 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6073 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 6074 6075 /* Verify write to second cluster */ 6076 6077 iov[0].iov_base = payload_ff; 6078 iov[0].iov_len = 2 * 512; 6079 spdk_blob_io_writev(blob, channel, iov, 1, 32 + 12, 2, blob_op_complete, NULL); 6080 poll_threads(); 6081 6082 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6083 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6084 6085 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6086 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 6087 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6088 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6089 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6090 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6091 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6092 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6093 6094 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6095 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 6096 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 6097 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 6098 } 6099 6100 static void 6101 test_iov_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6102 { 6103 uint8_t payload_read[64 * 512]; 6104 uint8_t payload_ff[64 * 512]; 6105 uint8_t payload_aa[64 * 512]; 6106 uint8_t payload_00[64 * 512]; 6107 struct iovec iov[4]; 6108 6109 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6110 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6111 memset(payload_00, 0x00, sizeof(payload_00)); 6112 6113 /* Read only first io unit */ 6114 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6115 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6116 * payload_read: F000 0000 | 0000 0000 ... */ 6117 memset(payload_read, 0x00, sizeof(payload_read)); 6118 iov[0].iov_base = payload_read; 6119 iov[0].iov_len = 1 * 512; 6120 spdk_blob_io_readv(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 6121 poll_threads(); 6122 6123 CU_ASSERT(g_bserrno == 0); 6124 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6125 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 6126 6127 /* Read four io_units starting from offset = 2 6128 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6129 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6130 * payload_read: F0AA 0000 | 0000 0000 ... */ 6131 6132 memset(payload_read, 0x00, sizeof(payload_read)); 6133 iov[0].iov_base = payload_read; 6134 iov[0].iov_len = 4 * 512; 6135 spdk_blob_io_readv(blob, channel, iov, 1, 2, 4, blob_op_complete, NULL); 6136 poll_threads(); 6137 CU_ASSERT(g_bserrno == 0); 6138 6139 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6140 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6141 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 6142 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 6143 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6144 6145 /* Read eight io_units across multiple pages 6146 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6147 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6148 * payload_read: AAAA AAAA | 0000 0000 ... */ 6149 memset(payload_read, 0x00, sizeof(payload_read)); 6150 iov[0].iov_base = payload_read; 6151 iov[0].iov_len = 4 * 512; 6152 iov[1].iov_base = payload_read + 4 * 512; 6153 iov[1].iov_len = 4 * 512; 6154 spdk_blob_io_readv(blob, channel, iov, 2, 4, 8, blob_op_complete, NULL); 6155 poll_threads(); 6156 CU_ASSERT(g_bserrno == 0); 6157 6158 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 6159 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6160 6161 /* Read eight io_units across multiple clusters 6162 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 6163 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6164 * payload_read: FFFF FFFF | 0000 0000 ... */ 6165 memset(payload_read, 0x00, sizeof(payload_read)); 6166 iov[0].iov_base = payload_read; 6167 iov[0].iov_len = 2 * 512; 6168 iov[1].iov_base = payload_read + 2 * 512; 6169 iov[1].iov_len = 2 * 512; 6170 iov[2].iov_base = payload_read + 4 * 512; 6171 iov[2].iov_len = 2 * 512; 6172 iov[3].iov_base = payload_read + 6 * 512; 6173 iov[3].iov_len = 2 * 512; 6174 spdk_blob_io_readv(blob, channel, iov, 4, 28, 8, blob_op_complete, NULL); 6175 poll_threads(); 6176 CU_ASSERT(g_bserrno == 0); 6177 6178 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 6179 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6180 6181 /* Read four io_units from second cluster 6182 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6183 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 6184 * payload_read: 00FF 0000 | 0000 0000 ... */ 6185 memset(payload_read, 0x00, sizeof(payload_read)); 6186 iov[0].iov_base = payload_read; 6187 iov[0].iov_len = 1 * 512; 6188 iov[1].iov_base = payload_read + 1 * 512; 6189 iov[1].iov_len = 3 * 512; 6190 spdk_blob_io_readv(blob, channel, iov, 2, 32 + 10, 4, blob_op_complete, NULL); 6191 poll_threads(); 6192 CU_ASSERT(g_bserrno == 0); 6193 6194 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 6195 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 6196 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6197 6198 /* Read second cluster 6199 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6200 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 6201 * payload_read: FFFF 0000 | 0000 FF00 ... */ 6202 memset(payload_read, 0x00, sizeof(payload_read)); 6203 iov[0].iov_base = payload_read; 6204 iov[0].iov_len = 1 * 512; 6205 iov[1].iov_base = payload_read + 1 * 512; 6206 iov[1].iov_len = 2 * 512; 6207 iov[2].iov_base = payload_read + 3 * 512; 6208 iov[2].iov_len = 4 * 512; 6209 iov[3].iov_base = payload_read + 7 * 512; 6210 iov[3].iov_len = 25 * 512; 6211 spdk_blob_io_readv(blob, channel, iov, 4, 32, 32, blob_op_complete, NULL); 6212 poll_threads(); 6213 CU_ASSERT(g_bserrno == 0); 6214 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 6215 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 6216 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 6217 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 6218 6219 /* Read whole two clusters 6220 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6221 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 6222 memset(payload_read, 0x00, sizeof(payload_read)); 6223 iov[0].iov_base = payload_read; 6224 iov[0].iov_len = 1 * 512; 6225 iov[1].iov_base = payload_read + 1 * 512; 6226 iov[1].iov_len = 8 * 512; 6227 iov[2].iov_base = payload_read + 9 * 512; 6228 iov[2].iov_len = 16 * 512; 6229 iov[3].iov_base = payload_read + 25 * 512; 6230 iov[3].iov_len = 39 * 512; 6231 spdk_blob_io_readv(blob, channel, iov, 4, 0, 64, blob_op_complete, NULL); 6232 poll_threads(); 6233 CU_ASSERT(g_bserrno == 0); 6234 6235 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6236 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6237 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 6238 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 6239 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 6240 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 6241 6242 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 6243 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 6244 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 6245 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 6246 } 6247 6248 static void 6249 blob_io_unit(void) 6250 { 6251 struct spdk_bs_opts bsopts; 6252 struct spdk_blob_opts opts; 6253 struct spdk_bs_dev *dev; 6254 struct spdk_blob *blob, *snapshot, *clone; 6255 spdk_blob_id blobid; 6256 struct spdk_io_channel *channel; 6257 6258 /* Create dev with 512 bytes io unit size */ 6259 6260 spdk_bs_opts_init(&bsopts); 6261 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 6262 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 6263 6264 /* Try to initialize a new blob store with unsupported io_unit */ 6265 dev = init_dev(); 6266 dev->blocklen = 512; 6267 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 6268 6269 /* Initialize a new blob store */ 6270 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 6271 poll_threads(); 6272 CU_ASSERT(g_bserrno == 0); 6273 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6274 6275 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512); 6276 channel = spdk_bs_alloc_io_channel(g_bs); 6277 6278 /* Create thick provisioned blob */ 6279 spdk_blob_opts_init(&opts); 6280 opts.thin_provision = false; 6281 opts.num_clusters = 32; 6282 6283 spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL); 6284 poll_threads(); 6285 6286 CU_ASSERT(g_bserrno == 0); 6287 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6288 blobid = g_blobid; 6289 6290 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 6291 poll_threads(); 6292 CU_ASSERT(g_bserrno == 0); 6293 CU_ASSERT(g_blob != NULL); 6294 blob = g_blob; 6295 6296 test_io_write(dev, blob, channel); 6297 test_io_read(dev, blob, channel); 6298 test_io_zeroes(dev, blob, channel); 6299 6300 test_iov_write(dev, blob, channel); 6301 test_iov_read(dev, blob, channel); 6302 6303 test_io_unmap(dev, blob, channel); 6304 6305 spdk_blob_close(blob, blob_op_complete, NULL); 6306 poll_threads(); 6307 CU_ASSERT(g_bserrno == 0); 6308 blob = NULL; 6309 g_blob = NULL; 6310 6311 /* Create thin provisioned blob */ 6312 6313 spdk_blob_opts_init(&opts); 6314 opts.thin_provision = true; 6315 opts.num_clusters = 32; 6316 6317 spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL); 6318 poll_threads(); 6319 CU_ASSERT(g_bserrno == 0); 6320 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6321 blobid = g_blobid; 6322 6323 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 6324 poll_threads(); 6325 CU_ASSERT(g_bserrno == 0); 6326 CU_ASSERT(g_blob != NULL); 6327 blob = g_blob; 6328 6329 test_io_write(dev, blob, channel); 6330 test_io_read(dev, blob, channel); 6331 6332 test_io_zeroes(dev, blob, channel); 6333 6334 test_iov_write(dev, blob, channel); 6335 test_iov_read(dev, blob, channel); 6336 6337 /* Create snapshot */ 6338 6339 spdk_bs_create_snapshot(g_bs, blobid, NULL, blob_op_with_id_complete, NULL); 6340 poll_threads(); 6341 CU_ASSERT(g_bserrno == 0); 6342 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6343 blobid = g_blobid; 6344 6345 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 6346 poll_threads(); 6347 CU_ASSERT(g_bserrno == 0); 6348 CU_ASSERT(g_blob != NULL); 6349 snapshot = g_blob; 6350 6351 spdk_bs_create_clone(g_bs, blobid, NULL, blob_op_with_id_complete, NULL); 6352 poll_threads(); 6353 CU_ASSERT(g_bserrno == 0); 6354 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6355 blobid = g_blobid; 6356 6357 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 6358 poll_threads(); 6359 CU_ASSERT(g_bserrno == 0); 6360 CU_ASSERT(g_blob != NULL); 6361 clone = g_blob; 6362 6363 test_io_read(dev, blob, channel); 6364 test_io_read(dev, snapshot, channel); 6365 test_io_read(dev, clone, channel); 6366 6367 test_iov_read(dev, blob, channel); 6368 test_iov_read(dev, snapshot, channel); 6369 test_iov_read(dev, clone, channel); 6370 6371 /* Inflate clone */ 6372 6373 spdk_bs_inflate_blob(g_bs, channel, blobid, blob_op_complete, NULL); 6374 poll_threads(); 6375 6376 CU_ASSERT(g_bserrno == 0); 6377 6378 test_io_read(dev, clone, channel); 6379 6380 test_io_unmap(dev, clone, channel); 6381 6382 test_iov_write(dev, clone, channel); 6383 test_iov_read(dev, clone, channel); 6384 6385 spdk_blob_close(blob, blob_op_complete, NULL); 6386 spdk_blob_close(snapshot, blob_op_complete, NULL); 6387 spdk_blob_close(clone, blob_op_complete, NULL); 6388 poll_threads(); 6389 CU_ASSERT(g_bserrno == 0); 6390 blob = NULL; 6391 g_blob = NULL; 6392 6393 /* Unload the blob store */ 6394 spdk_bs_unload(g_bs, bs_op_complete, NULL); 6395 poll_threads(); 6396 CU_ASSERT(g_bserrno == 0); 6397 g_bs = NULL; 6398 g_blob = NULL; 6399 g_blobid = 0; 6400 } 6401 6402 static void 6403 blob_io_unit_compatiblity(void) 6404 { 6405 struct spdk_bs_opts bsopts; 6406 struct spdk_bs_dev *dev; 6407 struct spdk_bs_super_block *super; 6408 6409 /* Create dev with 512 bytes io unit size */ 6410 6411 spdk_bs_opts_init(&bsopts); 6412 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 6413 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 6414 6415 /* Try to initialize a new blob store with unsupported io_unit */ 6416 dev = init_dev(); 6417 dev->blocklen = 512; 6418 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 6419 6420 /* Initialize a new blob store */ 6421 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 6422 poll_threads(); 6423 CU_ASSERT(g_bserrno == 0); 6424 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6425 6426 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512); 6427 6428 /* Unload the blob store */ 6429 spdk_bs_unload(g_bs, bs_op_complete, NULL); 6430 poll_threads(); 6431 CU_ASSERT(g_bserrno == 0); 6432 6433 /* Modify super block to behave like older version. 6434 * Check if loaded io unit size equals SPDK_BS_PAGE_SIZE */ 6435 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 6436 super->io_unit_size = 0; 6437 super->crc = _spdk_blob_md_page_calc_crc(super); 6438 6439 dev = init_dev(); 6440 dev->blocklen = 512; 6441 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 6442 6443 spdk_bs_load(dev, &bsopts, bs_op_with_handle_complete, NULL); 6444 poll_threads(); 6445 CU_ASSERT(g_bserrno == 0); 6446 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6447 6448 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == SPDK_BS_PAGE_SIZE); 6449 6450 /* Unload the blob store */ 6451 spdk_bs_unload(g_bs, bs_op_complete, NULL); 6452 poll_threads(); 6453 CU_ASSERT(g_bserrno == 0); 6454 6455 g_bs = NULL; 6456 g_blob = NULL; 6457 g_blobid = 0; 6458 } 6459 6460 int main(int argc, char **argv) 6461 { 6462 CU_pSuite suite = NULL; 6463 unsigned int num_failures; 6464 6465 if (CU_initialize_registry() != CUE_SUCCESS) { 6466 return CU_get_error(); 6467 } 6468 6469 suite = CU_add_suite("blob", NULL, NULL); 6470 if (suite == NULL) { 6471 CU_cleanup_registry(); 6472 return CU_get_error(); 6473 } 6474 6475 if ( 6476 CU_add_test(suite, "blob_init", blob_init) == NULL || 6477 CU_add_test(suite, "blob_open", blob_open) == NULL || 6478 CU_add_test(suite, "blob_create", blob_create) == NULL || 6479 CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL || 6480 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 6481 CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL || 6482 CU_add_test(suite, "blob_clone", blob_clone) == NULL || 6483 CU_add_test(suite, "blob_inflate", blob_inflate) == NULL || 6484 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 6485 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 6486 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 6487 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 6488 CU_add_test(suite, "blob_super", blob_super) == NULL || 6489 CU_add_test(suite, "blob_write", blob_write) == NULL || 6490 CU_add_test(suite, "blob_read", blob_read) == NULL || 6491 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 6492 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 6493 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 6494 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 6495 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 6496 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 6497 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 6498 CU_add_test(suite, "bs_load", bs_load) == NULL || 6499 CU_add_test(suite, "bs_load_custom_cluster_size", bs_load_custom_cluster_size) == NULL || 6500 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 6501 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 6502 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 6503 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 6504 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 6505 CU_add_test(suite, "bs_type", bs_type) == NULL || 6506 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 6507 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 6508 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 6509 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 6510 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 6511 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 6512 CU_add_test(suite, "bs_version", bs_version) == NULL || 6513 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 6514 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 6515 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 6516 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 6517 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL || 6518 CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL || 6519 CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL || 6520 CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL || 6521 CU_add_test(suite, "blob_relations", blob_relations) == NULL || 6522 CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL || 6523 CU_add_test(suite, "blob_snapshot_freeze_io", blob_snapshot_freeze_io) == NULL || 6524 CU_add_test(suite, "blob_operation_split_rw", blob_operation_split_rw) == NULL || 6525 CU_add_test(suite, "blob_operation_split_rw_iov", blob_operation_split_rw_iov) == NULL || 6526 CU_add_test(suite, "blob_io_unit", blob_io_unit) == NULL || 6527 CU_add_test(suite, "blob_io_unit_compatiblity", blob_io_unit_compatiblity) == NULL 6528 ) { 6529 CU_cleanup_registry(); 6530 return CU_get_error(); 6531 } 6532 6533 allocate_threads(1); 6534 set_thread(0); 6535 6536 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 6537 6538 CU_basic_set_mode(CU_BRM_VERBOSE); 6539 CU_basic_run_tests(); 6540 num_failures = CU_get_number_of_failures(); 6541 CU_cleanup_registry(); 6542 6543 free(g_dev_buffer); 6544 6545 free_threads(); 6546 6547 return num_failures; 6548 } 6549