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 poll_threads(); 3543 CU_ASSERT(g_bserrno == 0); 3544 blob = NULL; 3545 g_blob = NULL; 3546 g_blobid = SPDK_BLOBID_INVALID; 3547 3548 /* Dirty shutdown */ 3549 _spdk_bs_free(g_bs); 3550 3551 /* reload blobstore */ 3552 dev = init_dev(); 3553 spdk_bs_opts_init(&opts); 3554 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3555 poll_threads(); 3556 CU_ASSERT(g_bserrno == 0); 3557 3558 /* Get the super blob */ 3559 spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL); 3560 poll_threads(); 3561 CU_ASSERT(g_bserrno == 0); 3562 CU_ASSERT(blobid1 == g_blobid); 3563 3564 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3565 poll_threads(); 3566 CU_ASSERT(g_bserrno == 0); 3567 CU_ASSERT(g_blob != NULL); 3568 blob = g_blob; 3569 3570 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3571 3572 /* Get the xattrs */ 3573 value = NULL; 3574 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3575 CU_ASSERT(rc == 0); 3576 SPDK_CU_ASSERT_FATAL(value != NULL); 3577 CU_ASSERT(*(uint64_t *)value == length); 3578 CU_ASSERT(value_len == 8); 3579 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3580 3581 /* Resize the blob */ 3582 spdk_blob_resize(blob, 20, blob_op_complete, NULL); 3583 poll_threads(); 3584 CU_ASSERT(g_bserrno == 0); 3585 3586 free_clusters = spdk_bs_free_cluster_count(g_bs); 3587 3588 spdk_blob_close(blob, blob_op_complete, NULL); 3589 poll_threads(); 3590 CU_ASSERT(g_bserrno == 0); 3591 blob = NULL; 3592 g_blob = NULL; 3593 g_blobid = SPDK_BLOBID_INVALID; 3594 3595 /* Dirty shutdown */ 3596 _spdk_bs_free(g_bs); 3597 3598 /* reload the blobstore */ 3599 dev = init_dev(); 3600 spdk_bs_opts_init(&opts); 3601 /* Load an existing blob store */ 3602 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3603 poll_threads(); 3604 CU_ASSERT(g_bserrno == 0); 3605 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3606 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3607 poll_threads(); 3608 CU_ASSERT(g_bserrno == 0); 3609 CU_ASSERT(g_blob != NULL); 3610 blob = g_blob; 3611 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 3612 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3613 3614 spdk_blob_close(blob, blob_op_complete, NULL); 3615 poll_threads(); 3616 CU_ASSERT(g_bserrno == 0); 3617 blob = NULL; 3618 g_blob = NULL; 3619 g_blobid = SPDK_BLOBID_INVALID; 3620 3621 /* Create second blob */ 3622 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3623 poll_threads(); 3624 CU_ASSERT(g_bserrno == 0); 3625 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3626 blobid2 = g_blobid; 3627 3628 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3629 poll_threads(); 3630 CU_ASSERT(g_bserrno == 0); 3631 CU_ASSERT(g_blob != NULL); 3632 blob = g_blob; 3633 3634 /* Set some xattrs */ 3635 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3636 CU_ASSERT(rc == 0); 3637 3638 length = 5432; 3639 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3640 CU_ASSERT(rc == 0); 3641 3642 /* Resize the blob */ 3643 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3644 poll_threads(); 3645 CU_ASSERT(g_bserrno == 0); 3646 3647 free_clusters = spdk_bs_free_cluster_count(g_bs); 3648 3649 spdk_blob_close(blob, blob_op_complete, NULL); 3650 poll_threads(); 3651 CU_ASSERT(g_bserrno == 0); 3652 blob = NULL; 3653 g_blob = NULL; 3654 g_blobid = SPDK_BLOBID_INVALID; 3655 3656 /* Dirty shutdown */ 3657 _spdk_bs_free(g_bs); 3658 3659 /* reload the blobstore */ 3660 dev = init_dev(); 3661 spdk_bs_opts_init(&opts); 3662 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3663 poll_threads(); 3664 CU_ASSERT(g_bserrno == 0); 3665 3666 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3667 poll_threads(); 3668 CU_ASSERT(g_bserrno == 0); 3669 CU_ASSERT(g_blob != NULL); 3670 blob = g_blob; 3671 3672 /* Get the xattrs */ 3673 value = NULL; 3674 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3675 CU_ASSERT(rc == 0); 3676 SPDK_CU_ASSERT_FATAL(value != NULL); 3677 CU_ASSERT(*(uint64_t *)value == length); 3678 CU_ASSERT(value_len == 8); 3679 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3680 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3681 3682 spdk_blob_close(blob, blob_op_complete, NULL); 3683 poll_threads(); 3684 CU_ASSERT(g_bserrno == 0); 3685 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 3686 poll_threads(); 3687 CU_ASSERT(g_bserrno == 0); 3688 3689 free_clusters = spdk_bs_free_cluster_count(g_bs); 3690 3691 /* Dirty shutdown */ 3692 _spdk_bs_free(g_bs); 3693 /* reload the blobstore */ 3694 dev = init_dev(); 3695 spdk_bs_opts_init(&opts); 3696 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3697 poll_threads(); 3698 CU_ASSERT(g_bserrno == 0); 3699 3700 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3701 poll_threads(); 3702 CU_ASSERT(g_bserrno != 0); 3703 CU_ASSERT(g_blob == NULL); 3704 3705 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3706 poll_threads(); 3707 CU_ASSERT(g_bserrno == 0); 3708 CU_ASSERT(g_blob != NULL); 3709 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3710 spdk_blob_close(g_blob, blob_op_complete, NULL); 3711 poll_threads(); 3712 CU_ASSERT(g_bserrno == 0); 3713 3714 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3715 poll_threads(); 3716 CU_ASSERT(g_bserrno == 0); 3717 g_bs = NULL; 3718 3719 /* reload the blobstore */ 3720 dev = init_dev(); 3721 spdk_bs_opts_init(&opts); 3722 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3723 poll_threads(); 3724 CU_ASSERT(g_bserrno == 0); 3725 3726 /* Create second blob */ 3727 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3728 poll_threads(); 3729 CU_ASSERT(g_bserrno == 0); 3730 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3731 blobid2 = g_blobid; 3732 3733 /* Create third blob */ 3734 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3735 poll_threads(); 3736 CU_ASSERT(g_bserrno == 0); 3737 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3738 blobid3 = g_blobid; 3739 3740 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3741 poll_threads(); 3742 CU_ASSERT(g_bserrno == 0); 3743 CU_ASSERT(g_blob != NULL); 3744 blob = g_blob; 3745 3746 /* Set some xattrs for second blob */ 3747 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3748 CU_ASSERT(rc == 0); 3749 3750 length = 5432; 3751 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3752 CU_ASSERT(rc == 0); 3753 3754 spdk_blob_close(blob, blob_op_complete, NULL); 3755 poll_threads(); 3756 CU_ASSERT(g_bserrno == 0); 3757 blob = NULL; 3758 g_blob = NULL; 3759 g_blobid = SPDK_BLOBID_INVALID; 3760 3761 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 3762 poll_threads(); 3763 CU_ASSERT(g_bserrno == 0); 3764 CU_ASSERT(g_blob != NULL); 3765 blob = g_blob; 3766 3767 /* Set some xattrs for third blob */ 3768 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 3769 CU_ASSERT(rc == 0); 3770 3771 length = 5432; 3772 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3773 CU_ASSERT(rc == 0); 3774 3775 spdk_blob_close(blob, blob_op_complete, NULL); 3776 poll_threads(); 3777 CU_ASSERT(g_bserrno == 0); 3778 blob = NULL; 3779 g_blob = NULL; 3780 g_blobid = SPDK_BLOBID_INVALID; 3781 3782 /* Mark second blob as invalid */ 3783 page_num = _spdk_bs_blobid_to_page(blobid2); 3784 3785 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 3786 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3787 page->sequence_num = 1; 3788 page->crc = _spdk_blob_md_page_calc_crc(page); 3789 3790 free_clusters = spdk_bs_free_cluster_count(g_bs); 3791 3792 /* Dirty shutdown */ 3793 _spdk_bs_free(g_bs); 3794 /* reload the blobstore */ 3795 dev = init_dev(); 3796 spdk_bs_opts_init(&opts); 3797 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3798 poll_threads(); 3799 CU_ASSERT(g_bserrno == 0); 3800 3801 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3802 poll_threads(); 3803 CU_ASSERT(g_bserrno != 0); 3804 CU_ASSERT(g_blob == NULL); 3805 3806 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 3807 poll_threads(); 3808 CU_ASSERT(g_bserrno == 0); 3809 CU_ASSERT(g_blob != NULL); 3810 blob = g_blob; 3811 3812 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3813 3814 spdk_blob_close(blob, blob_op_complete, NULL); 3815 poll_threads(); 3816 CU_ASSERT(g_bserrno == 0); 3817 blob = NULL; 3818 g_blob = NULL; 3819 g_blobid = SPDK_BLOBID_INVALID; 3820 3821 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3822 poll_threads(); 3823 CU_ASSERT(g_bserrno == 0); 3824 g_bs = NULL; 3825 } 3826 3827 static void 3828 blob_flags(void) 3829 { 3830 struct spdk_bs_dev *dev; 3831 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 3832 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 3833 struct spdk_bs_opts opts; 3834 int rc; 3835 3836 dev = init_dev(); 3837 spdk_bs_opts_init(&opts); 3838 3839 /* Initialize a new blob store */ 3840 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3841 poll_threads(); 3842 CU_ASSERT(g_bserrno == 0); 3843 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3844 3845 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 3846 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3847 poll_threads(); 3848 CU_ASSERT(g_bserrno == 0); 3849 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3850 blobid_invalid = g_blobid; 3851 3852 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3853 poll_threads(); 3854 CU_ASSERT(g_bserrno == 0); 3855 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3856 blobid_data_ro = g_blobid; 3857 3858 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3859 poll_threads(); 3860 CU_ASSERT(g_bserrno == 0); 3861 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3862 blobid_md_ro = g_blobid; 3863 3864 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 3865 poll_threads(); 3866 CU_ASSERT(g_bserrno == 0); 3867 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3868 blob_invalid = g_blob; 3869 3870 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 3871 poll_threads(); 3872 CU_ASSERT(g_bserrno == 0); 3873 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3874 blob_data_ro = g_blob; 3875 3876 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 3877 poll_threads(); 3878 CU_ASSERT(g_bserrno == 0); 3879 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3880 blob_md_ro = g_blob; 3881 3882 /* Change the size of blob_data_ro to check if flags are serialized 3883 * when blob has non zero number of extents */ 3884 spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL); 3885 poll_threads(); 3886 CU_ASSERT(g_bserrno == 0); 3887 3888 /* Set the xattr to check if flags are serialized 3889 * when blob has non zero number of xattrs */ 3890 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 3891 CU_ASSERT(rc == 0); 3892 3893 blob_invalid->invalid_flags = (1ULL << 63); 3894 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 3895 blob_data_ro->data_ro_flags = (1ULL << 62); 3896 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 3897 blob_md_ro->md_ro_flags = (1ULL << 61); 3898 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 3899 3900 g_bserrno = -1; 3901 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 3902 poll_threads(); 3903 CU_ASSERT(g_bserrno == 0); 3904 g_bserrno = -1; 3905 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 3906 poll_threads(); 3907 CU_ASSERT(g_bserrno == 0); 3908 g_bserrno = -1; 3909 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 3910 poll_threads(); 3911 CU_ASSERT(g_bserrno == 0); 3912 3913 g_bserrno = -1; 3914 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 3915 poll_threads(); 3916 CU_ASSERT(g_bserrno == 0); 3917 blob_invalid = NULL; 3918 g_bserrno = -1; 3919 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 3920 poll_threads(); 3921 CU_ASSERT(g_bserrno == 0); 3922 blob_data_ro = NULL; 3923 g_bserrno = -1; 3924 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 3925 poll_threads(); 3926 CU_ASSERT(g_bserrno == 0); 3927 blob_md_ro = NULL; 3928 3929 g_blob = NULL; 3930 g_blobid = SPDK_BLOBID_INVALID; 3931 3932 /* Unload the blob store */ 3933 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3934 poll_threads(); 3935 CU_ASSERT(g_bserrno == 0); 3936 g_bs = NULL; 3937 3938 /* Load an existing blob store */ 3939 dev = init_dev(); 3940 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3941 poll_threads(); 3942 CU_ASSERT(g_bserrno == 0); 3943 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3944 3945 g_blob = NULL; 3946 g_bserrno = 0; 3947 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 3948 poll_threads(); 3949 CU_ASSERT(g_bserrno != 0); 3950 CU_ASSERT(g_blob == NULL); 3951 3952 g_blob = NULL; 3953 g_bserrno = -1; 3954 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 3955 poll_threads(); 3956 CU_ASSERT(g_bserrno == 0); 3957 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3958 blob_data_ro = g_blob; 3959 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 3960 CU_ASSERT(blob_data_ro->data_ro == true); 3961 CU_ASSERT(blob_data_ro->md_ro == true); 3962 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 3963 3964 g_blob = NULL; 3965 g_bserrno = -1; 3966 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 3967 poll_threads(); 3968 CU_ASSERT(g_bserrno == 0); 3969 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3970 blob_md_ro = g_blob; 3971 CU_ASSERT(blob_md_ro->data_ro == false); 3972 CU_ASSERT(blob_md_ro->md_ro == true); 3973 3974 g_bserrno = -1; 3975 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 3976 poll_threads(); 3977 CU_ASSERT(g_bserrno == 0); 3978 3979 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 3980 poll_threads(); 3981 CU_ASSERT(g_bserrno == 0); 3982 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 3983 poll_threads(); 3984 CU_ASSERT(g_bserrno == 0); 3985 3986 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3987 poll_threads(); 3988 CU_ASSERT(g_bserrno == 0); 3989 } 3990 3991 static void 3992 bs_version(void) 3993 { 3994 struct spdk_bs_super_block *super; 3995 struct spdk_bs_dev *dev; 3996 struct spdk_bs_opts opts; 3997 spdk_blob_id blobid; 3998 3999 dev = init_dev(); 4000 spdk_bs_opts_init(&opts); 4001 4002 /* Initialize a new blob store */ 4003 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 4004 poll_threads(); 4005 CU_ASSERT(g_bserrno == 0); 4006 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4007 4008 /* Unload the blob store */ 4009 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4010 poll_threads(); 4011 CU_ASSERT(g_bserrno == 0); 4012 g_bs = NULL; 4013 4014 /* 4015 * Change the bs version on disk. This will allow us to 4016 * test that the version does not get modified automatically 4017 * when loading and unloading the blobstore. 4018 */ 4019 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 4020 CU_ASSERT(super->version == SPDK_BS_VERSION); 4021 CU_ASSERT(super->clean == 1); 4022 super->version = 2; 4023 /* 4024 * Version 2 metadata does not have a used blobid mask, so clear 4025 * those fields in the super block and zero the corresponding 4026 * region on "disk". We will use this to ensure blob IDs are 4027 * correctly reconstructed. 4028 */ 4029 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 4030 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 4031 super->used_blobid_mask_start = 0; 4032 super->used_blobid_mask_len = 0; 4033 super->crc = _spdk_blob_md_page_calc_crc(super); 4034 4035 /* Load an existing blob store */ 4036 dev = init_dev(); 4037 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4038 poll_threads(); 4039 CU_ASSERT(g_bserrno == 0); 4040 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4041 CU_ASSERT(super->clean == 1); 4042 4043 /* 4044 * Create a blob - just to make sure that when we unload it 4045 * results in writing the super block (since metadata pages 4046 * were allocated. 4047 */ 4048 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 4049 poll_threads(); 4050 CU_ASSERT(g_bserrno == 0); 4051 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4052 blobid = g_blobid; 4053 4054 /* Unload the blob store */ 4055 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4056 poll_threads(); 4057 CU_ASSERT(g_bserrno == 0); 4058 g_bs = NULL; 4059 CU_ASSERT(super->version == 2); 4060 CU_ASSERT(super->used_blobid_mask_start == 0); 4061 CU_ASSERT(super->used_blobid_mask_len == 0); 4062 4063 dev = init_dev(); 4064 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4065 poll_threads(); 4066 CU_ASSERT(g_bserrno == 0); 4067 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4068 4069 g_blob = NULL; 4070 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 4071 poll_threads(); 4072 CU_ASSERT(g_bserrno == 0); 4073 CU_ASSERT(g_blob != NULL); 4074 4075 spdk_blob_close(g_blob, blob_op_complete, NULL); 4076 poll_threads(); 4077 CU_ASSERT(g_bserrno == 0); 4078 4079 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4080 poll_threads(); 4081 CU_ASSERT(g_bserrno == 0); 4082 g_bs = NULL; 4083 CU_ASSERT(super->version == 2); 4084 CU_ASSERT(super->used_blobid_mask_start == 0); 4085 CU_ASSERT(super->used_blobid_mask_len == 0); 4086 } 4087 4088 static void 4089 blob_set_xattrs(void) 4090 { 4091 struct spdk_blob_store *bs; 4092 struct spdk_bs_dev *dev; 4093 struct spdk_blob *blob; 4094 struct spdk_blob_opts opts; 4095 spdk_blob_id blobid; 4096 const void *value; 4097 size_t value_len; 4098 int rc; 4099 4100 dev = init_dev(); 4101 4102 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4103 poll_threads(); 4104 CU_ASSERT(g_bserrno == 0); 4105 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4106 bs = g_bs; 4107 4108 /* Create blob with extra attributes */ 4109 spdk_blob_opts_init(&opts); 4110 4111 opts.xattrs.names = g_xattr_names; 4112 opts.xattrs.get_value = _get_xattr_value; 4113 opts.xattrs.count = 3; 4114 opts.xattrs.ctx = &g_ctx; 4115 4116 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4117 poll_threads(); 4118 CU_ASSERT(g_bserrno == 0); 4119 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4120 blobid = g_blobid; 4121 4122 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4123 poll_threads(); 4124 CU_ASSERT(g_bserrno == 0); 4125 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4126 blob = g_blob; 4127 4128 /* Get the xattrs */ 4129 value = NULL; 4130 4131 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 4132 CU_ASSERT(rc == 0); 4133 SPDK_CU_ASSERT_FATAL(value != NULL); 4134 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 4135 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 4136 4137 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 4138 CU_ASSERT(rc == 0); 4139 SPDK_CU_ASSERT_FATAL(value != NULL); 4140 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 4141 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 4142 4143 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 4144 CU_ASSERT(rc == 0); 4145 SPDK_CU_ASSERT_FATAL(value != NULL); 4146 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 4147 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 4148 4149 /* Try to get non existing attribute */ 4150 4151 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 4152 CU_ASSERT(rc == -ENOENT); 4153 4154 spdk_blob_close(blob, blob_op_complete, NULL); 4155 poll_threads(); 4156 CU_ASSERT(g_bserrno == 0); 4157 blob = NULL; 4158 g_blob = NULL; 4159 g_blobid = SPDK_BLOBID_INVALID; 4160 4161 /* NULL callback */ 4162 spdk_blob_opts_init(&opts); 4163 opts.xattrs.names = g_xattr_names; 4164 opts.xattrs.get_value = NULL; 4165 opts.xattrs.count = 1; 4166 opts.xattrs.ctx = &g_ctx; 4167 4168 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4169 poll_threads(); 4170 CU_ASSERT(g_bserrno == -EINVAL); 4171 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4172 4173 /* NULL values */ 4174 spdk_blob_opts_init(&opts); 4175 opts.xattrs.names = g_xattr_names; 4176 opts.xattrs.get_value = _get_xattr_value_null; 4177 opts.xattrs.count = 1; 4178 opts.xattrs.ctx = NULL; 4179 4180 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4181 poll_threads(); 4182 CU_ASSERT(g_bserrno == -EINVAL); 4183 4184 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4185 poll_threads(); 4186 CU_ASSERT(g_bserrno == 0); 4187 g_bs = NULL; 4188 4189 } 4190 4191 static void 4192 blob_thin_prov_alloc(void) 4193 { 4194 struct spdk_blob_store *bs; 4195 struct spdk_bs_dev *dev; 4196 struct spdk_blob *blob; 4197 struct spdk_blob_opts opts; 4198 spdk_blob_id blobid; 4199 uint64_t free_clusters; 4200 4201 dev = init_dev(); 4202 4203 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4204 poll_threads(); 4205 CU_ASSERT(g_bserrno == 0); 4206 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4207 bs = g_bs; 4208 free_clusters = spdk_bs_free_cluster_count(bs); 4209 4210 /* Set blob as thin provisioned */ 4211 spdk_blob_opts_init(&opts); 4212 opts.thin_provision = true; 4213 4214 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4215 poll_threads(); 4216 CU_ASSERT(g_bserrno == 0); 4217 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4218 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4219 blobid = g_blobid; 4220 4221 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4222 poll_threads(); 4223 CU_ASSERT(g_bserrno == 0); 4224 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4225 blob = g_blob; 4226 4227 CU_ASSERT(blob->active.num_clusters == 0); 4228 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 4229 4230 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4231 spdk_blob_resize(blob, 5, 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 == 5); 4236 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4237 4238 /* Grow it to 1TB - still unallocated */ 4239 spdk_blob_resize(blob, 262144, blob_op_complete, NULL); 4240 poll_threads(); 4241 CU_ASSERT(g_bserrno == 0); 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 4246 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4247 poll_threads(); 4248 CU_ASSERT(g_bserrno == 0); 4249 /* Sync must not change anything */ 4250 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4251 CU_ASSERT(blob->active.num_clusters == 262144); 4252 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 4253 /* Since clusters are not allocated, 4254 * number of metadata pages is expected to be minimal. 4255 */ 4256 CU_ASSERT(blob->active.num_pages == 1); 4257 4258 /* Shrink the blob to 3 clusters - still unallocated */ 4259 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 4260 poll_threads(); 4261 CU_ASSERT(g_bserrno == 0); 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_sync_md(blob, blob_op_complete, NULL); 4267 poll_threads(); 4268 CU_ASSERT(g_bserrno == 0); 4269 /* Sync must not change anything */ 4270 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4271 CU_ASSERT(blob->active.num_clusters == 3); 4272 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 4273 4274 spdk_blob_close(blob, blob_op_complete, NULL); 4275 poll_threads(); 4276 CU_ASSERT(g_bserrno == 0); 4277 4278 /* Unload the blob store */ 4279 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4280 poll_threads(); 4281 CU_ASSERT(g_bserrno == 0); 4282 g_bs = NULL; 4283 g_blob = NULL; 4284 g_blobid = 0; 4285 4286 /* Load an existing blob store */ 4287 dev = init_dev(); 4288 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4289 poll_threads(); 4290 CU_ASSERT(g_bserrno == 0); 4291 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4292 4293 bs = g_bs; 4294 4295 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 4296 poll_threads(); 4297 CU_ASSERT(g_bserrno == 0); 4298 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4299 blob = g_blob; 4300 4301 /* Check that clusters allocation and size is still the same */ 4302 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4303 CU_ASSERT(blob->active.num_clusters == 3); 4304 4305 spdk_blob_close(blob, blob_op_complete, NULL); 4306 poll_threads(); 4307 CU_ASSERT(g_bserrno == 0); 4308 4309 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4310 poll_threads(); 4311 CU_ASSERT(g_bserrno == 0); 4312 4313 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4314 poll_threads(); 4315 CU_ASSERT(g_bserrno == 0); 4316 g_bs = NULL; 4317 } 4318 4319 static void 4320 blob_insert_cluster_msg(void) 4321 { 4322 struct spdk_blob_store *bs; 4323 struct spdk_bs_dev *dev; 4324 struct spdk_blob *blob; 4325 struct spdk_blob_opts opts; 4326 spdk_blob_id blobid; 4327 uint64_t free_clusters; 4328 4329 dev = init_dev(); 4330 4331 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4332 poll_threads(); 4333 CU_ASSERT(g_bserrno == 0); 4334 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4335 bs = g_bs; 4336 free_clusters = spdk_bs_free_cluster_count(bs); 4337 4338 /* Set blob as thin provisioned */ 4339 spdk_blob_opts_init(&opts); 4340 opts.thin_provision = true; 4341 opts.num_clusters = 4; 4342 4343 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4344 poll_threads(); 4345 CU_ASSERT(g_bserrno == 0); 4346 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4347 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4348 blobid = g_blobid; 4349 4350 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4351 poll_threads(); 4352 CU_ASSERT(g_bserrno == 0); 4353 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4354 blob = g_blob; 4355 4356 CU_ASSERT(blob->active.num_clusters == 4); 4357 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 4358 CU_ASSERT(blob->active.clusters[1] == 0); 4359 4360 _spdk_bs_claim_cluster(bs, 0xF); 4361 _spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL); 4362 poll_threads(); 4363 4364 CU_ASSERT(blob->active.clusters[1] != 0); 4365 4366 spdk_blob_close(blob, blob_op_complete, NULL); 4367 poll_threads(); 4368 CU_ASSERT(g_bserrno == 0); 4369 4370 /* Unload the blob store */ 4371 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4372 poll_threads(); 4373 CU_ASSERT(g_bserrno == 0); 4374 g_bs = NULL; 4375 g_blob = NULL; 4376 g_blobid = 0; 4377 4378 /* Load an existing blob store */ 4379 dev = init_dev(); 4380 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4381 poll_threads(); 4382 CU_ASSERT(g_bserrno == 0); 4383 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4384 4385 bs = g_bs; 4386 4387 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 4388 poll_threads(); 4389 CU_ASSERT(g_bserrno == 0); 4390 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4391 blob = g_blob; 4392 4393 CU_ASSERT(blob->active.clusters[1] != 0); 4394 4395 spdk_blob_close(blob, blob_op_complete, NULL); 4396 poll_threads(); 4397 CU_ASSERT(g_bserrno == 0); 4398 4399 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4400 poll_threads(); 4401 CU_ASSERT(g_bserrno == 0); 4402 4403 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4404 poll_threads(); 4405 CU_ASSERT(g_bserrno == 0); 4406 g_bs = NULL; 4407 } 4408 4409 static void 4410 blob_thin_prov_rw(void) 4411 { 4412 static const uint8_t zero[10 * 4096] = { 0 }; 4413 struct spdk_blob_store *bs; 4414 struct spdk_bs_dev *dev; 4415 struct spdk_blob *blob; 4416 struct spdk_io_channel *channel, *channel_thread1; 4417 struct spdk_blob_opts opts; 4418 spdk_blob_id blobid; 4419 uint64_t free_clusters; 4420 uint64_t page_size; 4421 uint8_t payload_read[10 * 4096]; 4422 uint8_t payload_write[10 * 4096]; 4423 uint64_t write_bytes; 4424 uint64_t read_bytes; 4425 4426 dev = init_dev(); 4427 4428 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4429 poll_threads(); 4430 CU_ASSERT(g_bserrno == 0); 4431 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4432 bs = g_bs; 4433 free_clusters = spdk_bs_free_cluster_count(bs); 4434 page_size = spdk_bs_get_page_size(bs); 4435 4436 channel = spdk_bs_alloc_io_channel(bs); 4437 CU_ASSERT(channel != NULL); 4438 4439 spdk_blob_opts_init(&opts); 4440 opts.thin_provision = true; 4441 4442 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4443 poll_threads(); 4444 CU_ASSERT(g_bserrno == 0); 4445 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4446 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4447 blobid = g_blobid; 4448 4449 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4450 poll_threads(); 4451 CU_ASSERT(g_bserrno == 0); 4452 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4453 blob = g_blob; 4454 4455 CU_ASSERT(blob->active.num_clusters == 0); 4456 4457 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4458 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4459 poll_threads(); 4460 CU_ASSERT(g_bserrno == 0); 4461 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4462 CU_ASSERT(blob->active.num_clusters == 5); 4463 4464 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4465 poll_threads(); 4466 CU_ASSERT(g_bserrno == 0); 4467 /* Sync must not change anything */ 4468 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4469 CU_ASSERT(blob->active.num_clusters == 5); 4470 4471 /* Payload should be all zeros from unallocated clusters */ 4472 memset(payload_read, 0xFF, sizeof(payload_read)); 4473 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4474 poll_threads(); 4475 CU_ASSERT(g_bserrno == 0); 4476 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4477 4478 write_bytes = g_dev_write_bytes; 4479 read_bytes = g_dev_read_bytes; 4480 4481 /* Perform write on thread 1. That will allocate cluster on thread 0 via send_msg */ 4482 set_thread(1); 4483 channel_thread1 = spdk_bs_alloc_io_channel(bs); 4484 CU_ASSERT(channel_thread1 != NULL); 4485 memset(payload_write, 0xE5, sizeof(payload_write)); 4486 spdk_blob_io_write(blob, channel_thread1, payload_write, 4, 10, blob_op_complete, NULL); 4487 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4488 /* Perform write on thread 0. That will try to allocate cluster, 4489 * but fail due to another thread issuing the cluster allocation first. */ 4490 set_thread(0); 4491 memset(payload_write, 0xE5, sizeof(payload_write)); 4492 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4493 CU_ASSERT(free_clusters - 2 == spdk_bs_free_cluster_count(bs)); 4494 poll_threads(); 4495 CU_ASSERT(g_bserrno == 0); 4496 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4497 /* For thin-provisioned blob we need to write 20 pages plus one page metadata and 4498 * read 0 bytes */ 4499 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 21); 4500 CU_ASSERT(g_dev_read_bytes - read_bytes == 0); 4501 4502 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4503 poll_threads(); 4504 CU_ASSERT(g_bserrno == 0); 4505 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4506 4507 spdk_blob_close(blob, blob_op_complete, NULL); 4508 poll_threads(); 4509 CU_ASSERT(g_bserrno == 0); 4510 4511 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4512 poll_threads(); 4513 CU_ASSERT(g_bserrno == 0); 4514 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4515 4516 spdk_bs_free_io_channel(channel_thread1); 4517 spdk_bs_free_io_channel(channel); 4518 poll_threads(); 4519 4520 /* Unload the blob store */ 4521 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4522 poll_threads(); 4523 CU_ASSERT(g_bserrno == 0); 4524 g_bs = NULL; 4525 g_blob = NULL; 4526 g_blobid = 0; 4527 } 4528 4529 static void 4530 blob_thin_prov_rw_iov(void) 4531 { 4532 static const uint8_t zero[10 * 4096] = { 0 }; 4533 struct spdk_blob_store *bs; 4534 struct spdk_bs_dev *dev; 4535 struct spdk_blob *blob; 4536 struct spdk_io_channel *channel; 4537 struct spdk_blob_opts opts; 4538 spdk_blob_id blobid; 4539 uint64_t free_clusters; 4540 uint8_t payload_read[10 * 4096]; 4541 uint8_t payload_write[10 * 4096]; 4542 struct iovec iov_read[3]; 4543 struct iovec iov_write[3]; 4544 4545 dev = init_dev(); 4546 4547 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4548 poll_threads(); 4549 CU_ASSERT(g_bserrno == 0); 4550 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4551 bs = g_bs; 4552 free_clusters = spdk_bs_free_cluster_count(bs); 4553 4554 channel = spdk_bs_alloc_io_channel(bs); 4555 CU_ASSERT(channel != NULL); 4556 4557 spdk_blob_opts_init(&opts); 4558 opts.thin_provision = true; 4559 4560 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4561 poll_threads(); 4562 CU_ASSERT(g_bserrno == 0); 4563 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4564 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4565 blobid = g_blobid; 4566 4567 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4568 poll_threads(); 4569 CU_ASSERT(g_bserrno == 0); 4570 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4571 blob = g_blob; 4572 4573 CU_ASSERT(blob->active.num_clusters == 0); 4574 4575 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4576 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4577 poll_threads(); 4578 CU_ASSERT(g_bserrno == 0); 4579 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4580 CU_ASSERT(blob->active.num_clusters == 5); 4581 4582 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4583 poll_threads(); 4584 CU_ASSERT(g_bserrno == 0); 4585 /* Sync must not change anything */ 4586 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4587 CU_ASSERT(blob->active.num_clusters == 5); 4588 4589 /* Payload should be all zeros from unallocated clusters */ 4590 memset(payload_read, 0xAA, sizeof(payload_read)); 4591 iov_read[0].iov_base = payload_read; 4592 iov_read[0].iov_len = 3 * 4096; 4593 iov_read[1].iov_base = payload_read + 3 * 4096; 4594 iov_read[1].iov_len = 4 * 4096; 4595 iov_read[2].iov_base = payload_read + 7 * 4096; 4596 iov_read[2].iov_len = 3 * 4096; 4597 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4598 poll_threads(); 4599 CU_ASSERT(g_bserrno == 0); 4600 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4601 4602 memset(payload_write, 0xE5, sizeof(payload_write)); 4603 iov_write[0].iov_base = payload_write; 4604 iov_write[0].iov_len = 1 * 4096; 4605 iov_write[1].iov_base = payload_write + 1 * 4096; 4606 iov_write[1].iov_len = 5 * 4096; 4607 iov_write[2].iov_base = payload_write + 6 * 4096; 4608 iov_write[2].iov_len = 4 * 4096; 4609 4610 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 4611 poll_threads(); 4612 CU_ASSERT(g_bserrno == 0); 4613 4614 memset(payload_read, 0xAA, sizeof(payload_read)); 4615 iov_read[0].iov_base = payload_read; 4616 iov_read[0].iov_len = 3 * 4096; 4617 iov_read[1].iov_base = payload_read + 3 * 4096; 4618 iov_read[1].iov_len = 4 * 4096; 4619 iov_read[2].iov_base = payload_read + 7 * 4096; 4620 iov_read[2].iov_len = 3 * 4096; 4621 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4622 poll_threads(); 4623 CU_ASSERT(g_bserrno == 0); 4624 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4625 4626 spdk_blob_close(blob, blob_op_complete, NULL); 4627 poll_threads(); 4628 CU_ASSERT(g_bserrno == 0); 4629 4630 spdk_bs_free_io_channel(channel); 4631 poll_threads(); 4632 4633 /* Unload the blob store */ 4634 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4635 poll_threads(); 4636 CU_ASSERT(g_bserrno == 0); 4637 g_bs = NULL; 4638 g_blob = NULL; 4639 g_blobid = 0; 4640 } 4641 4642 struct iter_ctx { 4643 int current_iter; 4644 spdk_blob_id blobid[4]; 4645 }; 4646 4647 static void 4648 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 4649 { 4650 struct iter_ctx *iter_ctx = arg; 4651 spdk_blob_id blobid; 4652 4653 CU_ASSERT(bserrno == 0); 4654 blobid = spdk_blob_get_id(blob); 4655 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 4656 } 4657 4658 static void 4659 bs_load_iter(void) 4660 { 4661 struct spdk_bs_dev *dev; 4662 struct iter_ctx iter_ctx = { 0 }; 4663 struct spdk_blob *blob; 4664 int i, rc; 4665 struct spdk_bs_opts opts; 4666 4667 dev = init_dev(); 4668 spdk_bs_opts_init(&opts); 4669 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4670 4671 /* Initialize a new blob store */ 4672 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 4673 poll_threads(); 4674 CU_ASSERT(g_bserrno == 0); 4675 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4676 4677 for (i = 0; i < 4; i++) { 4678 g_bserrno = -1; 4679 g_blobid = SPDK_BLOBID_INVALID; 4680 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 4681 poll_threads(); 4682 CU_ASSERT(g_bserrno == 0); 4683 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4684 iter_ctx.blobid[i] = g_blobid; 4685 4686 g_bserrno = -1; 4687 g_blob = NULL; 4688 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 4689 poll_threads(); 4690 CU_ASSERT(g_bserrno == 0); 4691 CU_ASSERT(g_blob != NULL); 4692 blob = g_blob; 4693 4694 /* Just save the blobid as an xattr for testing purposes. */ 4695 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 4696 CU_ASSERT(rc == 0); 4697 4698 /* Resize the blob */ 4699 spdk_blob_resize(blob, i, blob_op_complete, NULL); 4700 poll_threads(); 4701 CU_ASSERT(g_bserrno == 0); 4702 4703 spdk_blob_close(blob, blob_op_complete, NULL); 4704 poll_threads(); 4705 CU_ASSERT(g_bserrno == 0); 4706 } 4707 4708 g_bserrno = -1; 4709 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4710 poll_threads(); 4711 CU_ASSERT(g_bserrno == 0); 4712 4713 dev = init_dev(); 4714 spdk_bs_opts_init(&opts); 4715 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4716 opts.iter_cb_fn = test_iter; 4717 opts.iter_cb_arg = &iter_ctx; 4718 4719 /* Test blob iteration during load after a clean shutdown. */ 4720 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4721 poll_threads(); 4722 CU_ASSERT(g_bserrno == 0); 4723 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4724 4725 /* Dirty shutdown */ 4726 _spdk_bs_free(g_bs); 4727 4728 dev = init_dev(); 4729 spdk_bs_opts_init(&opts); 4730 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4731 opts.iter_cb_fn = test_iter; 4732 iter_ctx.current_iter = 0; 4733 opts.iter_cb_arg = &iter_ctx; 4734 4735 /* Test blob iteration during load after a dirty shutdown. */ 4736 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4737 poll_threads(); 4738 CU_ASSERT(g_bserrno == 0); 4739 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4740 4741 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4742 poll_threads(); 4743 CU_ASSERT(g_bserrno == 0); 4744 g_bs = NULL; 4745 } 4746 4747 static void 4748 blob_snapshot_rw(void) 4749 { 4750 static const uint8_t zero[10 * 4096] = { 0 }; 4751 struct spdk_blob_store *bs; 4752 struct spdk_bs_dev *dev; 4753 struct spdk_blob *blob, *snapshot; 4754 struct spdk_io_channel *channel; 4755 struct spdk_blob_opts opts; 4756 spdk_blob_id blobid, snapshotid; 4757 uint64_t free_clusters; 4758 uint64_t cluster_size; 4759 uint64_t page_size; 4760 uint8_t payload_read[10 * 4096]; 4761 uint8_t payload_write[10 * 4096]; 4762 uint64_t write_bytes; 4763 uint64_t read_bytes; 4764 4765 dev = init_dev(); 4766 4767 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4768 poll_threads(); 4769 CU_ASSERT(g_bserrno == 0); 4770 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4771 bs = g_bs; 4772 free_clusters = spdk_bs_free_cluster_count(bs); 4773 cluster_size = spdk_bs_get_cluster_size(bs); 4774 page_size = spdk_bs_get_page_size(bs); 4775 4776 channel = spdk_bs_alloc_io_channel(bs); 4777 CU_ASSERT(channel != NULL); 4778 4779 spdk_blob_opts_init(&opts); 4780 opts.thin_provision = true; 4781 opts.num_clusters = 5; 4782 4783 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4784 poll_threads(); 4785 CU_ASSERT(g_bserrno == 0); 4786 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4787 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4788 blobid = g_blobid; 4789 4790 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4791 poll_threads(); 4792 CU_ASSERT(g_bserrno == 0); 4793 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4794 blob = g_blob; 4795 4796 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4797 4798 memset(payload_read, 0xFF, sizeof(payload_read)); 4799 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4800 poll_threads(); 4801 CU_ASSERT(g_bserrno == 0); 4802 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4803 4804 memset(payload_write, 0xE5, sizeof(payload_write)); 4805 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4806 poll_threads(); 4807 CU_ASSERT(g_bserrno == 0); 4808 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4809 4810 /* Create snapshot from blob */ 4811 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4812 poll_threads(); 4813 CU_ASSERT(g_bserrno == 0); 4814 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4815 snapshotid = g_blobid; 4816 4817 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4818 poll_threads(); 4819 CU_ASSERT(g_bserrno == 0); 4820 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4821 snapshot = g_blob; 4822 CU_ASSERT(snapshot->data_ro == true) 4823 CU_ASSERT(snapshot->md_ro == true) 4824 4825 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 4826 4827 write_bytes = g_dev_write_bytes; 4828 read_bytes = g_dev_read_bytes; 4829 4830 memset(payload_write, 0xAA, sizeof(payload_write)); 4831 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4832 poll_threads(); 4833 CU_ASSERT(g_bserrno == 0); 4834 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4835 4836 /* For a clone we need to allocate and copy one cluster, update one page of metadata 4837 * and then write 10 pages of payload. 4838 */ 4839 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11 + cluster_size); 4840 CU_ASSERT(g_dev_read_bytes - read_bytes == cluster_size); 4841 4842 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4843 poll_threads(); 4844 CU_ASSERT(g_bserrno == 0); 4845 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4846 4847 /* Data on snapshot should not change after write to clone */ 4848 memset(payload_write, 0xE5, sizeof(payload_write)); 4849 spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL); 4850 poll_threads(); 4851 CU_ASSERT(g_bserrno == 0); 4852 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4853 4854 spdk_blob_close(blob, blob_op_complete, NULL); 4855 poll_threads(); 4856 CU_ASSERT(g_bserrno == 0); 4857 4858 spdk_blob_close(snapshot, blob_op_complete, NULL); 4859 poll_threads(); 4860 CU_ASSERT(g_bserrno == 0); 4861 4862 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4863 poll_threads(); 4864 CU_ASSERT(g_bserrno == 0); 4865 4866 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4867 poll_threads(); 4868 CU_ASSERT(g_bserrno == 0); 4869 4870 spdk_bs_free_io_channel(channel); 4871 poll_threads(); 4872 4873 /* Unload the blob store */ 4874 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4875 poll_threads(); 4876 CU_ASSERT(g_bserrno == 0); 4877 g_bs = NULL; 4878 g_blob = NULL; 4879 g_blobid = 0; 4880 } 4881 4882 static void 4883 blob_snapshot_rw_iov(void) 4884 { 4885 static const uint8_t zero[10 * 4096] = { 0 }; 4886 struct spdk_blob_store *bs; 4887 struct spdk_bs_dev *dev; 4888 struct spdk_blob *blob, *snapshot; 4889 struct spdk_io_channel *channel; 4890 struct spdk_blob_opts opts; 4891 spdk_blob_id blobid, snapshotid; 4892 uint64_t free_clusters; 4893 uint8_t payload_read[10 * 4096]; 4894 uint8_t payload_write[10 * 4096]; 4895 struct iovec iov_read[3]; 4896 struct iovec iov_write[3]; 4897 4898 dev = init_dev(); 4899 4900 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4901 poll_threads(); 4902 CU_ASSERT(g_bserrno == 0); 4903 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4904 bs = g_bs; 4905 free_clusters = spdk_bs_free_cluster_count(bs); 4906 4907 channel = spdk_bs_alloc_io_channel(bs); 4908 CU_ASSERT(channel != NULL); 4909 4910 spdk_blob_opts_init(&opts); 4911 opts.thin_provision = true; 4912 opts.num_clusters = 5; 4913 4914 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4915 poll_threads(); 4916 CU_ASSERT(g_bserrno == 0); 4917 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4918 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4919 blobid = g_blobid; 4920 4921 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4922 poll_threads(); 4923 CU_ASSERT(g_bserrno == 0); 4924 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4925 blob = g_blob; 4926 4927 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4928 4929 /* Create snapshot from blob */ 4930 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4931 poll_threads(); 4932 CU_ASSERT(g_bserrno == 0); 4933 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4934 snapshotid = g_blobid; 4935 4936 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4937 poll_threads(); 4938 CU_ASSERT(g_bserrno == 0); 4939 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4940 snapshot = g_blob; 4941 CU_ASSERT(snapshot->data_ro == true) 4942 CU_ASSERT(snapshot->md_ro == true) 4943 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 4944 4945 /* Payload should be all zeros from unallocated clusters */ 4946 memset(payload_read, 0xAA, sizeof(payload_read)); 4947 iov_read[0].iov_base = payload_read; 4948 iov_read[0].iov_len = 3 * 4096; 4949 iov_read[1].iov_base = payload_read + 3 * 4096; 4950 iov_read[1].iov_len = 4 * 4096; 4951 iov_read[2].iov_base = payload_read + 7 * 4096; 4952 iov_read[2].iov_len = 3 * 4096; 4953 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4954 poll_threads(); 4955 CU_ASSERT(g_bserrno == 0); 4956 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4957 4958 memset(payload_write, 0xE5, sizeof(payload_write)); 4959 iov_write[0].iov_base = payload_write; 4960 iov_write[0].iov_len = 1 * 4096; 4961 iov_write[1].iov_base = payload_write + 1 * 4096; 4962 iov_write[1].iov_len = 5 * 4096; 4963 iov_write[2].iov_base = payload_write + 6 * 4096; 4964 iov_write[2].iov_len = 4 * 4096; 4965 4966 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 4967 poll_threads(); 4968 CU_ASSERT(g_bserrno == 0); 4969 4970 memset(payload_read, 0xAA, sizeof(payload_read)); 4971 iov_read[0].iov_base = payload_read; 4972 iov_read[0].iov_len = 3 * 4096; 4973 iov_read[1].iov_base = payload_read + 3 * 4096; 4974 iov_read[1].iov_len = 4 * 4096; 4975 iov_read[2].iov_base = payload_read + 7 * 4096; 4976 iov_read[2].iov_len = 3 * 4096; 4977 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4978 poll_threads(); 4979 CU_ASSERT(g_bserrno == 0); 4980 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4981 4982 spdk_blob_close(blob, blob_op_complete, NULL); 4983 poll_threads(); 4984 CU_ASSERT(g_bserrno == 0); 4985 4986 spdk_blob_close(snapshot, blob_op_complete, NULL); 4987 poll_threads(); 4988 CU_ASSERT(g_bserrno == 0); 4989 4990 spdk_bs_free_io_channel(channel); 4991 poll_threads(); 4992 4993 /* Unload the blob store */ 4994 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4995 poll_threads(); 4996 CU_ASSERT(g_bserrno == 0); 4997 g_bs = NULL; 4998 g_blob = NULL; 4999 g_blobid = 0; 5000 } 5001 5002 /** 5003 * Inflate / decouple parent rw unit tests. 5004 * 5005 * -------------- 5006 * original blob: 0 1 2 3 4 5007 * ,---------+---------+---------+---------+---------. 5008 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 5009 * +---------+---------+---------+---------+---------+ 5010 * snapshot2 | - |yyyyyyyyy| - |yyyyyyyyy| - | 5011 * +---------+---------+---------+---------+---------+ 5012 * blob | - |zzzzzzzzz| - | - | - | 5013 * '---------+---------+---------+---------+---------' 5014 * . . . . . . 5015 * -------- . . . . . . 5016 * inflate: . . . . . . 5017 * ,---------+---------+---------+---------+---------. 5018 * blob |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000| 5019 * '---------+---------+---------+---------+---------' 5020 * 5021 * NOTE: needs to allocate 4 clusters, thin provisioning removed, dependency 5022 * on snapshot2 and snapshot removed . . . 5023 * . . . . . . 5024 * ---------------- . . . . . . 5025 * decouple parent: . . . . . . 5026 * ,---------+---------+---------+---------+---------. 5027 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 5028 * +---------+---------+---------+---------+---------+ 5029 * blob | - |zzzzzzzzz| - |yyyyyyyyy| - | 5030 * '---------+---------+---------+---------+---------' 5031 * 5032 * NOTE: needs to allocate 1 cluster, 3 clusters unallocated, dependency 5033 * on snapshot2 removed and on snapshot still exists. Snapshot2 5034 * should remain a clone of snapshot. 5035 */ 5036 static void 5037 _blob_inflate_rw(bool decouple_parent) 5038 { 5039 struct spdk_blob_store *bs; 5040 struct spdk_bs_dev *dev; 5041 struct spdk_blob *blob, *snapshot, *snapshot2; 5042 struct spdk_io_channel *channel; 5043 struct spdk_blob_opts opts; 5044 spdk_blob_id blobid, snapshotid, snapshot2id; 5045 uint64_t free_clusters; 5046 uint64_t cluster_size; 5047 5048 uint64_t payload_size; 5049 uint8_t *payload_read; 5050 uint8_t *payload_write; 5051 uint8_t *payload_clone; 5052 5053 uint64_t pages_per_cluster; 5054 uint64_t pages_per_payload; 5055 5056 int i; 5057 spdk_blob_id ids[2]; 5058 size_t count; 5059 5060 dev = init_dev(); 5061 5062 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5063 poll_threads(); 5064 CU_ASSERT(g_bserrno == 0); 5065 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5066 bs = g_bs; 5067 5068 free_clusters = spdk_bs_free_cluster_count(bs); 5069 cluster_size = spdk_bs_get_cluster_size(bs); 5070 pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs); 5071 pages_per_payload = pages_per_cluster * 5; 5072 5073 payload_size = cluster_size * 5; 5074 5075 payload_read = malloc(payload_size); 5076 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 5077 5078 payload_write = malloc(payload_size); 5079 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 5080 5081 payload_clone = malloc(payload_size); 5082 SPDK_CU_ASSERT_FATAL(payload_clone != NULL); 5083 5084 channel = spdk_bs_alloc_io_channel(bs); 5085 SPDK_CU_ASSERT_FATAL(channel != NULL); 5086 5087 /* Create blob */ 5088 spdk_blob_opts_init(&opts); 5089 opts.thin_provision = true; 5090 opts.num_clusters = 5; 5091 5092 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5093 poll_threads(); 5094 CU_ASSERT(g_bserrno == 0); 5095 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5096 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5097 blobid = g_blobid; 5098 5099 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5100 poll_threads(); 5101 CU_ASSERT(g_bserrno == 0); 5102 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5103 blob = g_blob; 5104 5105 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5106 5107 /* 1) Initial read should return zeroed payload */ 5108 memset(payload_read, 0xFF, payload_size); 5109 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5110 blob_op_complete, NULL); 5111 poll_threads(); 5112 CU_ASSERT(g_bserrno == 0); 5113 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 5114 5115 /* Fill whole blob with a pattern, except last cluster (to be sure it 5116 * isn't allocated) */ 5117 memset(payload_write, 0xE5, payload_size - cluster_size); 5118 spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload - 5119 pages_per_cluster, blob_op_complete, NULL); 5120 poll_threads(); 5121 CU_ASSERT(g_bserrno == 0); 5122 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5123 5124 /* 2) Create snapshot from blob (first level) */ 5125 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5126 poll_threads(); 5127 CU_ASSERT(g_bserrno == 0); 5128 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5129 snapshotid = g_blobid; 5130 5131 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5132 poll_threads(); 5133 CU_ASSERT(g_bserrno == 0); 5134 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5135 snapshot = g_blob; 5136 CU_ASSERT(snapshot->data_ro == true) 5137 CU_ASSERT(snapshot->md_ro == true) 5138 5139 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 5140 5141 /* Write every second cluster with a pattern. 5142 * 5143 * Last cluster shouldn't be written, to be sure that snapshot nor clone 5144 * doesn't allocate it. 5145 * 5146 * payload_clone stores expected result on "blob" read at the time and 5147 * is used only to check data consistency on clone before and after 5148 * inflation. Initially we fill it with a backing snapshots pattern 5149 * used before. 5150 */ 5151 memset(payload_clone, 0xE5, payload_size - cluster_size); 5152 memset(payload_clone + payload_size - cluster_size, 0x00, cluster_size); 5153 memset(payload_write, 0xAA, payload_size); 5154 for (i = 1; i < 5; i += 2) { 5155 spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster, 5156 pages_per_cluster, blob_op_complete, NULL); 5157 poll_threads(); 5158 CU_ASSERT(g_bserrno == 0); 5159 5160 /* Update expected result */ 5161 memcpy(payload_clone + (cluster_size * i), payload_write, 5162 cluster_size); 5163 } 5164 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5165 5166 /* Check data consistency on clone */ 5167 memset(payload_read, 0xFF, payload_size); 5168 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5169 blob_op_complete, NULL); 5170 poll_threads(); 5171 CU_ASSERT(g_bserrno == 0); 5172 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5173 5174 /* 3) Create second levels snapshot from blob */ 5175 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5176 poll_threads(); 5177 CU_ASSERT(g_bserrno == 0); 5178 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5179 snapshot2id = g_blobid; 5180 5181 spdk_bs_open_blob(bs, snapshot2id, blob_op_with_handle_complete, NULL); 5182 poll_threads(); 5183 CU_ASSERT(g_bserrno == 0); 5184 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5185 snapshot2 = g_blob; 5186 CU_ASSERT(snapshot2->data_ro == true) 5187 CU_ASSERT(snapshot2->md_ro == true) 5188 5189 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 5) 5190 5191 CU_ASSERT(snapshot2->parent_id == snapshotid); 5192 5193 /* Write one cluster on the top level blob. This cluster (1) covers 5194 * already allocated cluster in the snapshot2, so shouldn't be inflated 5195 * at all */ 5196 spdk_blob_io_write(blob, channel, payload_write, pages_per_cluster, 5197 pages_per_cluster, blob_op_complete, NULL); 5198 poll_threads(); 5199 CU_ASSERT(g_bserrno == 0); 5200 5201 /* Update expected result */ 5202 memcpy(payload_clone + cluster_size, payload_write, cluster_size); 5203 5204 /* Check data consistency on clone */ 5205 memset(payload_read, 0xFF, payload_size); 5206 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5207 blob_op_complete, NULL); 5208 poll_threads(); 5209 CU_ASSERT(g_bserrno == 0); 5210 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5211 5212 5213 /* Close all blobs */ 5214 spdk_blob_close(blob, blob_op_complete, NULL); 5215 poll_threads(); 5216 CU_ASSERT(g_bserrno == 0); 5217 5218 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5219 poll_threads(); 5220 CU_ASSERT(g_bserrno == 0); 5221 5222 spdk_blob_close(snapshot, blob_op_complete, NULL); 5223 poll_threads(); 5224 CU_ASSERT(g_bserrno == 0); 5225 5226 /* Check snapshot-clone relations */ 5227 count = 2; 5228 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5229 CU_ASSERT(count == 1); 5230 CU_ASSERT(ids[0] == snapshot2id); 5231 5232 count = 2; 5233 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5234 CU_ASSERT(count == 1); 5235 CU_ASSERT(ids[0] == blobid); 5236 5237 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshot2id); 5238 5239 free_clusters = spdk_bs_free_cluster_count(bs); 5240 if (!decouple_parent) { 5241 /* Do full blob inflation */ 5242 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 5243 poll_threads(); 5244 CU_ASSERT(g_bserrno == 0); 5245 5246 /* All clusters should be inflated (except one already allocated 5247 * in a top level blob) */ 5248 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 4); 5249 5250 /* Check if relation tree updated correctly */ 5251 count = 2; 5252 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5253 5254 /* snapshotid have one clone */ 5255 CU_ASSERT(count == 1); 5256 CU_ASSERT(ids[0] == snapshot2id); 5257 5258 /* snapshot2id have no clones */ 5259 count = 2; 5260 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5261 CU_ASSERT(count == 0); 5262 5263 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5264 } else { 5265 /* Decouple parent of blob */ 5266 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 5267 poll_threads(); 5268 CU_ASSERT(g_bserrno == 0); 5269 5270 /* Only one cluster from a parent should be inflated (second one 5271 * is covered by a cluster written on a top level blob, and 5272 * already allocated) */ 5273 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 1); 5274 5275 /* Check if relation tree updated correctly */ 5276 count = 2; 5277 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5278 5279 /* snapshotid have two clones now */ 5280 CU_ASSERT(count == 2); 5281 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5282 CU_ASSERT(ids[0] == snapshot2id || ids[1] == snapshot2id); 5283 5284 /* snapshot2id have no clones */ 5285 count = 2; 5286 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5287 CU_ASSERT(count == 0); 5288 5289 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5290 } 5291 5292 /* Try to delete snapshot2 (should pass) */ 5293 spdk_bs_delete_blob(bs, snapshot2id, blob_op_complete, NULL); 5294 poll_threads(); 5295 CU_ASSERT(g_bserrno == 0); 5296 5297 /* Try to delete base snapshot (for decouple_parent should fail while 5298 * dependency still exists) */ 5299 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5300 poll_threads(); 5301 CU_ASSERT(decouple_parent || g_bserrno == 0); 5302 CU_ASSERT(!decouple_parent || g_bserrno != 0); 5303 5304 /* Reopen blob after snapshot deletion */ 5305 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5306 poll_threads(); 5307 CU_ASSERT(g_bserrno == 0); 5308 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5309 blob = g_blob; 5310 5311 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5312 5313 /* Check data consistency on inflated blob */ 5314 memset(payload_read, 0xFF, payload_size); 5315 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5316 blob_op_complete, NULL); 5317 poll_threads(); 5318 CU_ASSERT(g_bserrno == 0); 5319 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5320 5321 spdk_blob_close(blob, blob_op_complete, NULL); 5322 poll_threads(); 5323 CU_ASSERT(g_bserrno == 0); 5324 5325 spdk_bs_free_io_channel(channel); 5326 poll_threads(); 5327 5328 /* Unload the blob store */ 5329 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5330 poll_threads(); 5331 CU_ASSERT(g_bserrno == 0); 5332 g_bs = NULL; 5333 g_blob = NULL; 5334 g_blobid = 0; 5335 5336 free(payload_read); 5337 free(payload_write); 5338 free(payload_clone); 5339 } 5340 5341 static void 5342 blob_inflate_rw(void) 5343 { 5344 _blob_inflate_rw(false); 5345 _blob_inflate_rw(true); 5346 } 5347 5348 /** 5349 * Snapshot-clones relation test 5350 * 5351 * snapshot 5352 * | 5353 * +-----+-----+ 5354 * | | 5355 * blob(ro) snapshot2 5356 * | | 5357 * clone2 clone 5358 */ 5359 static void 5360 blob_relations(void) 5361 { 5362 struct spdk_blob_store *bs; 5363 struct spdk_bs_dev *dev; 5364 struct spdk_bs_opts bs_opts; 5365 struct spdk_blob_opts opts; 5366 struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2; 5367 spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2; 5368 int rc; 5369 size_t count; 5370 spdk_blob_id ids[10] = {}; 5371 5372 dev = init_dev(); 5373 spdk_bs_opts_init(&bs_opts); 5374 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5375 5376 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 5377 poll_threads(); 5378 CU_ASSERT(g_bserrno == 0); 5379 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5380 bs = g_bs; 5381 5382 /* 1. Create blob with 10 clusters */ 5383 5384 spdk_blob_opts_init(&opts); 5385 opts.num_clusters = 10; 5386 5387 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5388 poll_threads(); 5389 CU_ASSERT(g_bserrno == 0); 5390 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5391 blobid = g_blobid; 5392 5393 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5394 poll_threads(); 5395 CU_ASSERT(g_bserrno == 0); 5396 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5397 blob = g_blob; 5398 5399 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5400 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5401 CU_ASSERT(!spdk_blob_is_clone(blob)); 5402 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob)); 5403 5404 /* blob should not have underlying snapshot nor clones */ 5405 CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID); 5406 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5407 count = SPDK_COUNTOF(ids); 5408 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5409 CU_ASSERT(rc == 0); 5410 CU_ASSERT(count == 0); 5411 5412 5413 /* 2. Create snapshot */ 5414 5415 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5416 poll_threads(); 5417 CU_ASSERT(g_bserrno == 0); 5418 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5419 snapshotid = g_blobid; 5420 5421 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5422 poll_threads(); 5423 CU_ASSERT(g_bserrno == 0); 5424 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5425 snapshot = g_blob; 5426 5427 CU_ASSERT(spdk_blob_is_read_only(snapshot)); 5428 CU_ASSERT(spdk_blob_is_snapshot(snapshot)); 5429 CU_ASSERT(!spdk_blob_is_clone(snapshot)); 5430 CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID); 5431 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5432 5433 /* Check if original blob is converted to the clone of snapshot */ 5434 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5435 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5436 CU_ASSERT(spdk_blob_is_clone(blob)); 5437 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5438 CU_ASSERT(blob->parent_id == snapshotid); 5439 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5440 5441 count = SPDK_COUNTOF(ids); 5442 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5443 CU_ASSERT(rc == 0); 5444 CU_ASSERT(count == 1); 5445 CU_ASSERT(ids[0] == blobid); 5446 5447 5448 /* 3. Create clone from snapshot */ 5449 5450 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 5451 poll_threads(); 5452 CU_ASSERT(g_bserrno == 0); 5453 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5454 cloneid = g_blobid; 5455 5456 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 5457 poll_threads(); 5458 CU_ASSERT(g_bserrno == 0); 5459 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5460 clone = g_blob; 5461 5462 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5463 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5464 CU_ASSERT(spdk_blob_is_clone(clone)); 5465 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5466 CU_ASSERT(clone->parent_id == snapshotid); 5467 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 5468 5469 count = SPDK_COUNTOF(ids); 5470 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5471 CU_ASSERT(rc == 0); 5472 CU_ASSERT(count == 0); 5473 5474 /* Check if clone is on the snapshot's list */ 5475 count = SPDK_COUNTOF(ids); 5476 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5477 CU_ASSERT(rc == 0); 5478 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5479 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 5480 5481 5482 /* 4. Create snapshot of the clone */ 5483 5484 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 5485 poll_threads(); 5486 CU_ASSERT(g_bserrno == 0); 5487 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5488 snapshotid2 = g_blobid; 5489 5490 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 5491 poll_threads(); 5492 CU_ASSERT(g_bserrno == 0); 5493 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5494 snapshot2 = g_blob; 5495 5496 CU_ASSERT(spdk_blob_is_read_only(snapshot2)); 5497 CU_ASSERT(spdk_blob_is_snapshot(snapshot2)); 5498 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 5499 CU_ASSERT(snapshot2->parent_id == snapshotid); 5500 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5501 5502 /* Check if clone is converted to the clone of snapshot2 and snapshot2 5503 * is a child of snapshot */ 5504 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5505 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5506 CU_ASSERT(spdk_blob_is_clone(clone)); 5507 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5508 CU_ASSERT(clone->parent_id == snapshotid2); 5509 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5510 5511 count = SPDK_COUNTOF(ids); 5512 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5513 CU_ASSERT(rc == 0); 5514 CU_ASSERT(count == 1); 5515 CU_ASSERT(ids[0] == cloneid); 5516 5517 5518 /* 5. Try to create clone from read only blob */ 5519 5520 /* Mark blob as read only */ 5521 spdk_blob_set_read_only(blob); 5522 spdk_blob_sync_md(blob, blob_op_complete, NULL); 5523 poll_threads(); 5524 CU_ASSERT(g_bserrno == 0); 5525 5526 /* Check if previously created blob is read only clone */ 5527 CU_ASSERT(spdk_blob_is_read_only(blob)); 5528 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5529 CU_ASSERT(spdk_blob_is_clone(blob)); 5530 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5531 5532 /* Create clone from read only blob */ 5533 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5534 poll_threads(); 5535 CU_ASSERT(g_bserrno == 0); 5536 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5537 cloneid2 = g_blobid; 5538 5539 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 5540 poll_threads(); 5541 CU_ASSERT(g_bserrno == 0); 5542 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5543 clone2 = g_blob; 5544 5545 CU_ASSERT(!spdk_blob_is_read_only(clone2)); 5546 CU_ASSERT(!spdk_blob_is_snapshot(clone2)); 5547 CU_ASSERT(spdk_blob_is_clone(clone2)); 5548 CU_ASSERT(spdk_blob_is_thin_provisioned(clone2)); 5549 5550 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5551 5552 count = SPDK_COUNTOF(ids); 5553 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5554 CU_ASSERT(rc == 0); 5555 5556 CU_ASSERT(count == 1); 5557 CU_ASSERT(ids[0] == cloneid2); 5558 5559 /* Close blobs */ 5560 5561 spdk_blob_close(clone2, blob_op_complete, NULL); 5562 poll_threads(); 5563 CU_ASSERT(g_bserrno == 0); 5564 5565 spdk_blob_close(blob, blob_op_complete, NULL); 5566 poll_threads(); 5567 CU_ASSERT(g_bserrno == 0); 5568 5569 spdk_blob_close(clone, blob_op_complete, NULL); 5570 poll_threads(); 5571 CU_ASSERT(g_bserrno == 0); 5572 5573 spdk_blob_close(snapshot, blob_op_complete, NULL); 5574 poll_threads(); 5575 CU_ASSERT(g_bserrno == 0); 5576 5577 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5578 poll_threads(); 5579 CU_ASSERT(g_bserrno == 0); 5580 5581 /* Try to delete snapshot with created clones */ 5582 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5583 poll_threads(); 5584 CU_ASSERT(g_bserrno != 0); 5585 5586 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5587 poll_threads(); 5588 CU_ASSERT(g_bserrno != 0); 5589 5590 spdk_bs_unload(bs, bs_op_complete, NULL); 5591 poll_threads(); 5592 CU_ASSERT(g_bserrno == 0); 5593 g_bs = NULL; 5594 5595 /* Load an existing blob store */ 5596 dev = init_dev(); 5597 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5598 5599 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 5600 poll_threads(); 5601 CU_ASSERT(g_bserrno == 0); 5602 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5603 bs = g_bs; 5604 5605 5606 /* NULL ids array should return number of clones in count */ 5607 count = SPDK_COUNTOF(ids); 5608 rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count); 5609 CU_ASSERT(rc == -ENOMEM); 5610 CU_ASSERT(count == 2); 5611 5612 /* incorrect array size */ 5613 count = 1; 5614 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5615 CU_ASSERT(rc == -ENOMEM); 5616 CU_ASSERT(count == 2); 5617 5618 5619 /* Verify structure of loaded blob store */ 5620 5621 /* snapshot */ 5622 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5623 5624 count = SPDK_COUNTOF(ids); 5625 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5626 CU_ASSERT(rc == 0); 5627 CU_ASSERT(count == 2); 5628 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5629 CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2); 5630 5631 /* blob */ 5632 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5633 count = SPDK_COUNTOF(ids); 5634 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5635 CU_ASSERT(rc == 0); 5636 CU_ASSERT(count == 1); 5637 CU_ASSERT(ids[0] == cloneid2); 5638 5639 /* clone */ 5640 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5641 count = SPDK_COUNTOF(ids); 5642 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5643 CU_ASSERT(rc == 0); 5644 CU_ASSERT(count == 0); 5645 5646 /* snapshot2 */ 5647 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5648 count = SPDK_COUNTOF(ids); 5649 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5650 CU_ASSERT(rc == 0); 5651 CU_ASSERT(count == 1); 5652 CU_ASSERT(ids[0] == cloneid); 5653 5654 /* clone2 */ 5655 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5656 count = SPDK_COUNTOF(ids); 5657 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 5658 CU_ASSERT(rc == 0); 5659 CU_ASSERT(count == 0); 5660 5661 /* Try to delete all blobs in the worse possible order */ 5662 5663 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5664 poll_threads(); 5665 CU_ASSERT(g_bserrno != 0); 5666 5667 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5668 poll_threads(); 5669 CU_ASSERT(g_bserrno != 0); 5670 5671 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 5672 poll_threads(); 5673 CU_ASSERT(g_bserrno == 0); 5674 5675 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5676 poll_threads(); 5677 CU_ASSERT(g_bserrno == 0); 5678 5679 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5680 poll_threads(); 5681 CU_ASSERT(g_bserrno != 0); 5682 5683 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5684 poll_threads(); 5685 CU_ASSERT(g_bserrno != 0); 5686 5687 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 5688 poll_threads(); 5689 CU_ASSERT(g_bserrno == 0); 5690 5691 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5692 poll_threads(); 5693 CU_ASSERT(g_bserrno == 0); 5694 5695 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5696 poll_threads(); 5697 CU_ASSERT(g_bserrno == 0); 5698 5699 spdk_bs_unload(bs, bs_op_complete, NULL); 5700 poll_threads(); 5701 CU_ASSERT(g_bserrno == 0); 5702 5703 g_bs = NULL; 5704 } 5705 5706 static void 5707 test_io_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5708 { 5709 uint8_t payload_ff[64 * 512]; 5710 uint8_t payload_aa[64 * 512]; 5711 uint8_t payload_00[64 * 512]; 5712 uint8_t *cluster0, *cluster1; 5713 5714 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5715 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5716 memset(payload_00, 0x00, sizeof(payload_00)); 5717 5718 /* Try to perform I/O with io unit = 512 */ 5719 spdk_blob_io_write(blob, channel, payload_ff, 0, 1, blob_op_complete, NULL); 5720 poll_threads(); 5721 CU_ASSERT(g_bserrno == 0); 5722 5723 /* If thin provisioned is set cluster should be allocated now */ 5724 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 5725 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 5726 5727 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 5728 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 5729 /* cluster0: [ F000 0000 | 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, 31 * 512) == 0); 5732 5733 /* Verify write with offset on first page */ 5734 spdk_blob_io_write(blob, channel, payload_ff, 2, 1, blob_op_complete, NULL); 5735 poll_threads(); 5736 CU_ASSERT(g_bserrno == 0); 5737 5738 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5739 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5740 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5741 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5742 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5743 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 5744 5745 /* Verify write with offset on first page */ 5746 spdk_blob_io_write(blob, channel, payload_ff, 4, 4, blob_op_complete, NULL); 5747 poll_threads(); 5748 5749 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5750 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5751 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5752 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5753 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5754 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 5755 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 5756 5757 /* Verify write with offset on second page */ 5758 spdk_blob_io_write(blob, channel, payload_ff, 8, 4, blob_op_complete, NULL); 5759 poll_threads(); 5760 5761 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 5762 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5763 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5764 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5765 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5766 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 5767 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 5768 5769 /* Verify write across multiple pages */ 5770 spdk_blob_io_write(blob, channel, payload_aa, 4, 8, blob_op_complete, NULL); 5771 poll_threads(); 5772 5773 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 5774 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5775 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5776 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5777 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5778 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 5779 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 5780 5781 /* Verify write across multiple clusters */ 5782 spdk_blob_io_write(blob, channel, payload_ff, 28, 8, blob_op_complete, NULL); 5783 poll_threads(); 5784 5785 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 5786 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5787 5788 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5789 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 5790 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5791 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5792 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5793 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5794 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 5795 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 5796 5797 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 5798 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 5799 5800 /* Verify write to second cluster */ 5801 spdk_blob_io_write(blob, channel, payload_ff, 32 + 12, 2, blob_op_complete, NULL); 5802 poll_threads(); 5803 5804 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 5805 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5806 5807 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5808 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 5809 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 5810 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 5811 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 5812 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 5813 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 5814 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 5815 5816 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 5817 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 5818 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 5819 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 5820 } 5821 5822 static void 5823 test_io_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5824 { 5825 uint8_t payload_read[64 * 512]; 5826 uint8_t payload_ff[64 * 512]; 5827 uint8_t payload_aa[64 * 512]; 5828 uint8_t payload_00[64 * 512]; 5829 5830 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5831 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5832 memset(payload_00, 0x00, sizeof(payload_00)); 5833 5834 /* Read only first io unit */ 5835 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5836 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5837 * payload_read: F000 0000 | 0000 0000 ... */ 5838 memset(payload_read, 0x00, sizeof(payload_read)); 5839 spdk_blob_io_read(blob, channel, payload_read, 0, 1, blob_op_complete, NULL); 5840 poll_threads(); 5841 CU_ASSERT(g_bserrno == 0); 5842 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 5843 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 5844 5845 /* Read four io_units starting from offset = 2 5846 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5847 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5848 * payload_read: F0AA 0000 | 0000 0000 ... */ 5849 5850 memset(payload_read, 0x00, sizeof(payload_read)); 5851 spdk_blob_io_read(blob, channel, payload_read, 2, 4, blob_op_complete, NULL); 5852 poll_threads(); 5853 CU_ASSERT(g_bserrno == 0); 5854 5855 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 5856 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 5857 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 5858 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 5859 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 5860 5861 /* Read eight io_units across multiple pages 5862 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 5863 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5864 * payload_read: AAAA AAAA | 0000 0000 ... */ 5865 memset(payload_read, 0x00, sizeof(payload_read)); 5866 spdk_blob_io_read(blob, channel, payload_read, 4, 8, blob_op_complete, NULL); 5867 poll_threads(); 5868 CU_ASSERT(g_bserrno == 0); 5869 5870 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 5871 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 5872 5873 /* Read eight io_units across multiple clusters 5874 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 5875 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 5876 * payload_read: FFFF FFFF | 0000 0000 ... */ 5877 memset(payload_read, 0x00, sizeof(payload_read)); 5878 spdk_blob_io_read(blob, channel, payload_read, 28, 8, blob_op_complete, NULL); 5879 poll_threads(); 5880 CU_ASSERT(g_bserrno == 0); 5881 5882 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 5883 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 5884 5885 /* Read four io_units from second cluster 5886 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5887 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 5888 * payload_read: 00FF 0000 | 0000 0000 ... */ 5889 memset(payload_read, 0x00, sizeof(payload_read)); 5890 spdk_blob_io_read(blob, channel, payload_read, 32 + 10, 4, blob_op_complete, NULL); 5891 poll_threads(); 5892 CU_ASSERT(g_bserrno == 0); 5893 5894 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 5895 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 5896 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 5897 5898 /* Read second cluster 5899 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 5900 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 5901 * payload_read: FFFF 0000 | 0000 FF00 ... */ 5902 memset(payload_read, 0x00, sizeof(payload_read)); 5903 spdk_blob_io_read(blob, channel, payload_read, 32, 32, blob_op_complete, NULL); 5904 poll_threads(); 5905 CU_ASSERT(g_bserrno == 0); 5906 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 5907 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 5908 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 5909 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 5910 5911 /* Read whole two clusters 5912 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 5913 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 5914 memset(payload_read, 0x00, sizeof(payload_read)); 5915 spdk_blob_io_read(blob, channel, payload_read, 0, 64, blob_op_complete, NULL); 5916 poll_threads(); 5917 CU_ASSERT(g_bserrno == 0); 5918 5919 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 5920 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 5921 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 5922 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 5923 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 5924 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 5925 5926 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 5927 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 5928 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 5929 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 5930 } 5931 5932 5933 static void 5934 test_io_unmap(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5935 { 5936 uint8_t payload_ff[64 * 512]; 5937 uint8_t payload_aa[64 * 512]; 5938 uint8_t payload_00[64 * 512]; 5939 uint8_t *cluster0, *cluster1; 5940 5941 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5942 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5943 memset(payload_00, 0x00, sizeof(payload_00)); 5944 5945 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 5946 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5947 5948 /* Unmap */ 5949 spdk_blob_io_unmap(blob, channel, 0, 64, blob_op_complete, NULL); 5950 poll_threads(); 5951 5952 CU_ASSERT(g_bserrno == 0); 5953 5954 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 5955 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 5956 } 5957 5958 static void 5959 test_io_zeroes(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5960 { 5961 uint8_t payload_ff[64 * 512]; 5962 uint8_t payload_aa[64 * 512]; 5963 uint8_t payload_00[64 * 512]; 5964 uint8_t *cluster0, *cluster1; 5965 5966 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5967 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5968 memset(payload_00, 0x00, sizeof(payload_00)); 5969 5970 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 5971 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 5972 5973 /* Write zeroes */ 5974 spdk_blob_io_write_zeroes(blob, channel, 0, 64, blob_op_complete, NULL); 5975 poll_threads(); 5976 5977 CU_ASSERT(g_bserrno == 0); 5978 5979 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 5980 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 5981 } 5982 5983 5984 static void 5985 test_iov_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 5986 { 5987 uint8_t payload_ff[64 * 512]; 5988 uint8_t payload_aa[64 * 512]; 5989 uint8_t payload_00[64 * 512]; 5990 uint8_t *cluster0, *cluster1; 5991 struct iovec iov[4]; 5992 5993 memset(payload_ff, 0xFF, sizeof(payload_ff)); 5994 memset(payload_aa, 0xAA, sizeof(payload_aa)); 5995 memset(payload_00, 0x00, sizeof(payload_00)); 5996 5997 /* Try to perform I/O with io unit = 512 */ 5998 iov[0].iov_base = payload_ff; 5999 iov[0].iov_len = 1 * 512; 6000 spdk_blob_io_writev(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 6001 poll_threads(); 6002 CU_ASSERT(g_bserrno == 0); 6003 6004 /* If thin provisioned is set cluster should be allocated now */ 6005 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 6006 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6007 6008 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 6009 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 6010 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6011 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6012 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 6013 6014 /* Verify write with offset on first page */ 6015 iov[0].iov_base = payload_ff; 6016 iov[0].iov_len = 1 * 512; 6017 spdk_blob_io_writev(blob, channel, iov, 1, 2, 1, blob_op_complete, NULL); 6018 poll_threads(); 6019 CU_ASSERT(g_bserrno == 0); 6020 6021 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6022 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6023 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6024 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6025 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6026 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 6027 6028 /* Verify write with offset on first page */ 6029 iov[0].iov_base = payload_ff; 6030 iov[0].iov_len = 4 * 512; 6031 spdk_blob_io_writev(blob, channel, iov, 1, 4, 4, blob_op_complete, NULL); 6032 poll_threads(); 6033 6034 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6035 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6036 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6037 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6038 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6039 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 6040 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 6041 6042 /* Verify write with offset on second page */ 6043 iov[0].iov_base = payload_ff; 6044 iov[0].iov_len = 4 * 512; 6045 spdk_blob_io_writev(blob, channel, iov, 1, 8, 4, blob_op_complete, NULL); 6046 poll_threads(); 6047 6048 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 6049 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6050 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6051 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6052 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6053 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 6054 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6055 6056 /* Verify write across multiple pages */ 6057 iov[0].iov_base = payload_aa; 6058 iov[0].iov_len = 8 * 512; 6059 spdk_blob_io_writev(blob, channel, iov, 1, 4, 8, blob_op_complete, NULL); 6060 poll_threads(); 6061 6062 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 6063 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6064 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6065 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6066 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6067 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6068 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6069 6070 /* Verify write across multiple clusters */ 6071 6072 iov[0].iov_base = payload_ff; 6073 iov[0].iov_len = 8 * 512; 6074 spdk_blob_io_writev(blob, channel, iov, 1, 28, 8, blob_op_complete, NULL); 6075 poll_threads(); 6076 6077 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6078 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6079 6080 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6081 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6082 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6083 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6084 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6085 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6086 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6087 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 16 * 512) == 0); 6088 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6089 6090 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6091 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 6092 6093 /* Verify write to second cluster */ 6094 6095 iov[0].iov_base = payload_ff; 6096 iov[0].iov_len = 2 * 512; 6097 spdk_blob_io_writev(blob, channel, iov, 1, 32 + 12, 2, blob_op_complete, NULL); 6098 poll_threads(); 6099 6100 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6101 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6102 6103 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6104 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 6105 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6106 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6107 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6108 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6109 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6110 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6111 6112 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6113 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 6114 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 6115 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 6116 } 6117 6118 static void 6119 test_iov_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6120 { 6121 uint8_t payload_read[64 * 512]; 6122 uint8_t payload_ff[64 * 512]; 6123 uint8_t payload_aa[64 * 512]; 6124 uint8_t payload_00[64 * 512]; 6125 struct iovec iov[4]; 6126 6127 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6128 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6129 memset(payload_00, 0x00, sizeof(payload_00)); 6130 6131 /* Read only first io unit */ 6132 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6133 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6134 * payload_read: F000 0000 | 0000 0000 ... */ 6135 memset(payload_read, 0x00, sizeof(payload_read)); 6136 iov[0].iov_base = payload_read; 6137 iov[0].iov_len = 1 * 512; 6138 spdk_blob_io_readv(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 6139 poll_threads(); 6140 6141 CU_ASSERT(g_bserrno == 0); 6142 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6143 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 6144 6145 /* Read four io_units starting from offset = 2 6146 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6147 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6148 * payload_read: F0AA 0000 | 0000 0000 ... */ 6149 6150 memset(payload_read, 0x00, sizeof(payload_read)); 6151 iov[0].iov_base = payload_read; 6152 iov[0].iov_len = 4 * 512; 6153 spdk_blob_io_readv(blob, channel, iov, 1, 2, 4, blob_op_complete, NULL); 6154 poll_threads(); 6155 CU_ASSERT(g_bserrno == 0); 6156 6157 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6158 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6159 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 6160 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 6161 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6162 6163 /* Read eight io_units across multiple pages 6164 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6165 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6166 * payload_read: AAAA AAAA | 0000 0000 ... */ 6167 memset(payload_read, 0x00, sizeof(payload_read)); 6168 iov[0].iov_base = payload_read; 6169 iov[0].iov_len = 4 * 512; 6170 iov[1].iov_base = payload_read + 4 * 512; 6171 iov[1].iov_len = 4 * 512; 6172 spdk_blob_io_readv(blob, channel, iov, 2, 4, 8, blob_op_complete, NULL); 6173 poll_threads(); 6174 CU_ASSERT(g_bserrno == 0); 6175 6176 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 6177 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6178 6179 /* Read eight io_units across multiple clusters 6180 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 6181 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6182 * payload_read: FFFF FFFF | 0000 0000 ... */ 6183 memset(payload_read, 0x00, sizeof(payload_read)); 6184 iov[0].iov_base = payload_read; 6185 iov[0].iov_len = 2 * 512; 6186 iov[1].iov_base = payload_read + 2 * 512; 6187 iov[1].iov_len = 2 * 512; 6188 iov[2].iov_base = payload_read + 4 * 512; 6189 iov[2].iov_len = 2 * 512; 6190 iov[3].iov_base = payload_read + 6 * 512; 6191 iov[3].iov_len = 2 * 512; 6192 spdk_blob_io_readv(blob, channel, iov, 4, 28, 8, blob_op_complete, NULL); 6193 poll_threads(); 6194 CU_ASSERT(g_bserrno == 0); 6195 6196 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 6197 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6198 6199 /* Read four io_units from second cluster 6200 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6201 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 6202 * payload_read: 00FF 0000 | 0000 0000 ... */ 6203 memset(payload_read, 0x00, sizeof(payload_read)); 6204 iov[0].iov_base = payload_read; 6205 iov[0].iov_len = 1 * 512; 6206 iov[1].iov_base = payload_read + 1 * 512; 6207 iov[1].iov_len = 3 * 512; 6208 spdk_blob_io_readv(blob, channel, iov, 2, 32 + 10, 4, blob_op_complete, NULL); 6209 poll_threads(); 6210 CU_ASSERT(g_bserrno == 0); 6211 6212 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 6213 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 6214 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6215 6216 /* Read second cluster 6217 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6218 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 6219 * payload_read: FFFF 0000 | 0000 FF00 ... */ 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 = 2 * 512; 6225 iov[2].iov_base = payload_read + 3 * 512; 6226 iov[2].iov_len = 4 * 512; 6227 iov[3].iov_base = payload_read + 7 * 512; 6228 iov[3].iov_len = 25 * 512; 6229 spdk_blob_io_readv(blob, channel, iov, 4, 32, 32, blob_op_complete, NULL); 6230 poll_threads(); 6231 CU_ASSERT(g_bserrno == 0); 6232 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 6233 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 6234 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 6235 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 6236 6237 /* Read whole two clusters 6238 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6239 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 6240 memset(payload_read, 0x00, sizeof(payload_read)); 6241 iov[0].iov_base = payload_read; 6242 iov[0].iov_len = 1 * 512; 6243 iov[1].iov_base = payload_read + 1 * 512; 6244 iov[1].iov_len = 8 * 512; 6245 iov[2].iov_base = payload_read + 9 * 512; 6246 iov[2].iov_len = 16 * 512; 6247 iov[3].iov_base = payload_read + 25 * 512; 6248 iov[3].iov_len = 39 * 512; 6249 spdk_blob_io_readv(blob, channel, iov, 4, 0, 64, blob_op_complete, NULL); 6250 poll_threads(); 6251 CU_ASSERT(g_bserrno == 0); 6252 6253 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6254 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6255 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 6256 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 6257 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 6258 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 6259 6260 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 6261 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 6262 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 6263 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 6264 } 6265 6266 static void 6267 blob_io_unit(void) 6268 { 6269 struct spdk_bs_opts bsopts; 6270 struct spdk_blob_opts opts; 6271 struct spdk_bs_dev *dev; 6272 struct spdk_blob *blob, *snapshot, *clone; 6273 spdk_blob_id blobid; 6274 struct spdk_io_channel *channel; 6275 6276 /* Create dev with 512 bytes io unit size */ 6277 6278 spdk_bs_opts_init(&bsopts); 6279 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 6280 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 6281 6282 /* Try to initialize a new blob store with unsupported io_unit */ 6283 dev = init_dev(); 6284 dev->blocklen = 512; 6285 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 6286 6287 /* Initialize a new blob store */ 6288 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 6289 poll_threads(); 6290 CU_ASSERT(g_bserrno == 0); 6291 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6292 6293 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512); 6294 channel = spdk_bs_alloc_io_channel(g_bs); 6295 6296 /* Create thick provisioned blob */ 6297 spdk_blob_opts_init(&opts); 6298 opts.thin_provision = false; 6299 opts.num_clusters = 32; 6300 6301 spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL); 6302 poll_threads(); 6303 6304 CU_ASSERT(g_bserrno == 0); 6305 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6306 blobid = g_blobid; 6307 6308 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 6309 poll_threads(); 6310 CU_ASSERT(g_bserrno == 0); 6311 CU_ASSERT(g_blob != NULL); 6312 blob = g_blob; 6313 6314 test_io_write(dev, blob, channel); 6315 test_io_read(dev, blob, channel); 6316 test_io_zeroes(dev, blob, channel); 6317 6318 test_iov_write(dev, blob, channel); 6319 test_iov_read(dev, blob, channel); 6320 6321 test_io_unmap(dev, blob, channel); 6322 6323 spdk_blob_close(blob, blob_op_complete, NULL); 6324 poll_threads(); 6325 CU_ASSERT(g_bserrno == 0); 6326 blob = NULL; 6327 g_blob = NULL; 6328 6329 /* Create thin provisioned blob */ 6330 6331 spdk_blob_opts_init(&opts); 6332 opts.thin_provision = true; 6333 opts.num_clusters = 32; 6334 6335 spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL); 6336 poll_threads(); 6337 CU_ASSERT(g_bserrno == 0); 6338 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6339 blobid = g_blobid; 6340 6341 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 6342 poll_threads(); 6343 CU_ASSERT(g_bserrno == 0); 6344 CU_ASSERT(g_blob != NULL); 6345 blob = g_blob; 6346 6347 test_io_write(dev, blob, channel); 6348 test_io_read(dev, blob, channel); 6349 6350 test_io_zeroes(dev, blob, channel); 6351 6352 test_iov_write(dev, blob, channel); 6353 test_iov_read(dev, blob, channel); 6354 6355 /* Create snapshot */ 6356 6357 spdk_bs_create_snapshot(g_bs, blobid, NULL, blob_op_with_id_complete, NULL); 6358 poll_threads(); 6359 CU_ASSERT(g_bserrno == 0); 6360 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6361 blobid = g_blobid; 6362 6363 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 6364 poll_threads(); 6365 CU_ASSERT(g_bserrno == 0); 6366 CU_ASSERT(g_blob != NULL); 6367 snapshot = g_blob; 6368 6369 spdk_bs_create_clone(g_bs, blobid, NULL, blob_op_with_id_complete, NULL); 6370 poll_threads(); 6371 CU_ASSERT(g_bserrno == 0); 6372 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6373 blobid = g_blobid; 6374 6375 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 6376 poll_threads(); 6377 CU_ASSERT(g_bserrno == 0); 6378 CU_ASSERT(g_blob != NULL); 6379 clone = g_blob; 6380 6381 test_io_read(dev, blob, channel); 6382 test_io_read(dev, snapshot, channel); 6383 test_io_read(dev, clone, channel); 6384 6385 test_iov_read(dev, blob, channel); 6386 test_iov_read(dev, snapshot, channel); 6387 test_iov_read(dev, clone, channel); 6388 6389 /* Inflate clone */ 6390 6391 spdk_bs_inflate_blob(g_bs, channel, blobid, blob_op_complete, NULL); 6392 poll_threads(); 6393 6394 CU_ASSERT(g_bserrno == 0); 6395 6396 test_io_read(dev, clone, channel); 6397 6398 test_io_unmap(dev, clone, channel); 6399 6400 test_iov_write(dev, clone, channel); 6401 test_iov_read(dev, clone, channel); 6402 6403 spdk_blob_close(blob, blob_op_complete, NULL); 6404 spdk_blob_close(snapshot, blob_op_complete, NULL); 6405 spdk_blob_close(clone, blob_op_complete, NULL); 6406 poll_threads(); 6407 CU_ASSERT(g_bserrno == 0); 6408 blob = NULL; 6409 g_blob = NULL; 6410 6411 /* Unload the blob store */ 6412 spdk_bs_unload(g_bs, bs_op_complete, NULL); 6413 poll_threads(); 6414 CU_ASSERT(g_bserrno == 0); 6415 g_bs = NULL; 6416 g_blob = NULL; 6417 g_blobid = 0; 6418 } 6419 6420 static void 6421 blob_io_unit_compatiblity(void) 6422 { 6423 struct spdk_bs_opts bsopts; 6424 struct spdk_bs_dev *dev; 6425 struct spdk_bs_super_block *super; 6426 6427 /* Create dev with 512 bytes io unit size */ 6428 6429 spdk_bs_opts_init(&bsopts); 6430 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 6431 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 6432 6433 /* Try to initialize a new blob store with unsupported io_unit */ 6434 dev = init_dev(); 6435 dev->blocklen = 512; 6436 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 6437 6438 /* Initialize a new blob store */ 6439 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 6440 poll_threads(); 6441 CU_ASSERT(g_bserrno == 0); 6442 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6443 6444 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512); 6445 6446 /* Unload the blob store */ 6447 spdk_bs_unload(g_bs, bs_op_complete, NULL); 6448 poll_threads(); 6449 CU_ASSERT(g_bserrno == 0); 6450 6451 /* Modify super block to behave like older version. 6452 * Check if loaded io unit size equals SPDK_BS_PAGE_SIZE */ 6453 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 6454 super->io_unit_size = 0; 6455 super->crc = _spdk_blob_md_page_calc_crc(super); 6456 6457 dev = init_dev(); 6458 dev->blocklen = 512; 6459 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 6460 6461 spdk_bs_load(dev, &bsopts, bs_op_with_handle_complete, NULL); 6462 poll_threads(); 6463 CU_ASSERT(g_bserrno == 0); 6464 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6465 6466 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == SPDK_BS_PAGE_SIZE); 6467 6468 /* Unload the blob store */ 6469 spdk_bs_unload(g_bs, bs_op_complete, NULL); 6470 poll_threads(); 6471 CU_ASSERT(g_bserrno == 0); 6472 6473 g_bs = NULL; 6474 g_blob = NULL; 6475 g_blobid = 0; 6476 } 6477 6478 static void 6479 blob_simultaneous_operations(void) 6480 { 6481 struct spdk_blob_store *bs; 6482 struct spdk_bs_dev *dev; 6483 struct spdk_blob_opts opts; 6484 struct spdk_blob *blob, *snapshot; 6485 spdk_blob_id blobid, snapshotid; 6486 struct spdk_io_channel *channel; 6487 6488 dev = init_dev(); 6489 6490 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 6491 poll_threads(); 6492 CU_ASSERT(g_bserrno == 0); 6493 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6494 bs = g_bs; 6495 6496 channel = spdk_bs_alloc_io_channel(bs); 6497 SPDK_CU_ASSERT_FATAL(channel != NULL); 6498 6499 spdk_blob_opts_init(&opts); 6500 opts.num_clusters = 10; 6501 6502 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 6503 poll_threads(); 6504 CU_ASSERT(g_bserrno == 0); 6505 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6506 blobid = g_blobid; 6507 6508 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 6509 poll_threads(); 6510 CU_ASSERT(g_bserrno == 0); 6511 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6512 blob = g_blob; 6513 6514 /* Create snapshot and try to remove blob in the same time: 6515 * - snapshot should be created successfully 6516 * - delete operation should fail w -EBUSY */ 6517 CU_ASSERT(blob->locked_operation_in_progress == false); 6518 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6519 CU_ASSERT(blob->locked_operation_in_progress == true); 6520 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 6521 CU_ASSERT(blob->locked_operation_in_progress == true); 6522 /* Deletion failure */ 6523 CU_ASSERT(g_bserrno == -EBUSY); 6524 poll_threads(); 6525 CU_ASSERT(blob->locked_operation_in_progress == false); 6526 /* Snapshot creation success */ 6527 CU_ASSERT(g_bserrno == 0); 6528 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6529 6530 snapshotid = g_blobid; 6531 6532 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 6533 poll_threads(); 6534 CU_ASSERT(g_bserrno == 0); 6535 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6536 snapshot = g_blob; 6537 6538 /* Inflate blob and try to remove blob in the same time: 6539 * - blob should be inflated successfully 6540 * - delete operation should fail w -EBUSY */ 6541 CU_ASSERT(blob->locked_operation_in_progress == false); 6542 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 6543 CU_ASSERT(blob->locked_operation_in_progress == true); 6544 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 6545 CU_ASSERT(blob->locked_operation_in_progress == true); 6546 /* Deletion failure */ 6547 CU_ASSERT(g_bserrno == -EBUSY); 6548 poll_threads(); 6549 CU_ASSERT(blob->locked_operation_in_progress == false); 6550 /* Inflation success */ 6551 CU_ASSERT(g_bserrno == 0); 6552 6553 /* Clone snapshot and try to remove snapshot in the same time: 6554 * - snapshot should be cloned successfully 6555 * - delete operation should fail w -EBUSY */ 6556 CU_ASSERT(blob->locked_operation_in_progress == false); 6557 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 6558 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 6559 /* Deletion failure */ 6560 CU_ASSERT(g_bserrno == -EBUSY); 6561 poll_threads(); 6562 CU_ASSERT(blob->locked_operation_in_progress == false); 6563 /* Clone created */ 6564 CU_ASSERT(g_bserrno == 0); 6565 6566 /* Resize blob and try to remove blob in the same time: 6567 * - blob should be resized successfully 6568 * - delete operation should fail w -EBUSY */ 6569 CU_ASSERT(blob->locked_operation_in_progress == false); 6570 spdk_blob_resize(blob, 50, blob_op_complete, NULL); 6571 CU_ASSERT(blob->locked_operation_in_progress == true); 6572 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 6573 CU_ASSERT(blob->locked_operation_in_progress == true); 6574 /* Deletion failure */ 6575 CU_ASSERT(g_bserrno == -EBUSY); 6576 poll_threads(); 6577 CU_ASSERT(blob->locked_operation_in_progress == false); 6578 /* Blob resized successfully */ 6579 CU_ASSERT(g_bserrno == 0); 6580 6581 spdk_blob_close(blob, blob_op_complete, NULL); 6582 poll_threads(); 6583 CU_ASSERT(g_bserrno == 0); 6584 6585 spdk_blob_close(snapshot, blob_op_complete, NULL); 6586 poll_threads(); 6587 CU_ASSERT(g_bserrno == 0); 6588 6589 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 6590 poll_threads(); 6591 CU_ASSERT(g_bserrno == 0); 6592 6593 spdk_bs_unload(g_bs, bs_op_complete, NULL); 6594 poll_threads(); 6595 CU_ASSERT(g_bserrno == 0); 6596 g_bs = NULL; 6597 6598 spdk_bs_free_io_channel(channel); 6599 poll_threads(); 6600 } 6601 6602 int main(int argc, char **argv) 6603 { 6604 CU_pSuite suite = NULL; 6605 unsigned int num_failures; 6606 6607 if (CU_initialize_registry() != CUE_SUCCESS) { 6608 return CU_get_error(); 6609 } 6610 6611 suite = CU_add_suite("blob", NULL, NULL); 6612 if (suite == NULL) { 6613 CU_cleanup_registry(); 6614 return CU_get_error(); 6615 } 6616 6617 if ( 6618 CU_add_test(suite, "blob_init", blob_init) == NULL || 6619 CU_add_test(suite, "blob_open", blob_open) == NULL || 6620 CU_add_test(suite, "blob_create", blob_create) == NULL || 6621 CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL || 6622 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 6623 CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL || 6624 CU_add_test(suite, "blob_clone", blob_clone) == NULL || 6625 CU_add_test(suite, "blob_inflate", blob_inflate) == NULL || 6626 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 6627 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 6628 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 6629 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 6630 CU_add_test(suite, "blob_super", blob_super) == NULL || 6631 CU_add_test(suite, "blob_write", blob_write) == NULL || 6632 CU_add_test(suite, "blob_read", blob_read) == NULL || 6633 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 6634 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 6635 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 6636 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 6637 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 6638 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 6639 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 6640 CU_add_test(suite, "bs_load", bs_load) == NULL || 6641 CU_add_test(suite, "bs_load_custom_cluster_size", bs_load_custom_cluster_size) == NULL || 6642 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 6643 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 6644 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 6645 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 6646 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 6647 CU_add_test(suite, "bs_type", bs_type) == NULL || 6648 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 6649 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 6650 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 6651 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 6652 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 6653 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 6654 CU_add_test(suite, "bs_version", bs_version) == NULL || 6655 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 6656 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 6657 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 6658 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 6659 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL || 6660 CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL || 6661 CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL || 6662 CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL || 6663 CU_add_test(suite, "blob_relations", blob_relations) == NULL || 6664 CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL || 6665 CU_add_test(suite, "blob_snapshot_freeze_io", blob_snapshot_freeze_io) == NULL || 6666 CU_add_test(suite, "blob_operation_split_rw", blob_operation_split_rw) == NULL || 6667 CU_add_test(suite, "blob_operation_split_rw_iov", blob_operation_split_rw_iov) == NULL || 6668 CU_add_test(suite, "blob_io_unit", blob_io_unit) == NULL || 6669 CU_add_test(suite, "blob_io_unit_compatiblity", blob_io_unit_compatiblity) == NULL || 6670 CU_add_test(suite, "blob_simultaneous_operations", blob_simultaneous_operations) == NULL 6671 ) { 6672 CU_cleanup_registry(); 6673 return CU_get_error(); 6674 } 6675 6676 allocate_threads(2); 6677 set_thread(0); 6678 6679 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 6680 6681 CU_basic_set_mode(CU_BRM_VERBOSE); 6682 CU_basic_run_tests(); 6683 num_failures = CU_get_number_of_failures(); 6684 CU_cleanup_registry(); 6685 6686 free(g_dev_buffer); 6687 6688 free_threads(); 6689 6690 return num_failures; 6691 } 6692