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