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_pending_removal(void) 2739 { 2740 struct spdk_blob_store *bs; 2741 struct spdk_bs_dev *dev; 2742 struct spdk_blob_opts opts; 2743 struct spdk_blob *blob, *snapshot; 2744 spdk_blob_id blobid, snapshotid; 2745 const void *value; 2746 size_t value_len; 2747 int rc; 2748 2749 dev = init_dev(); 2750 2751 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2752 poll_threads(); 2753 CU_ASSERT(g_bserrno == 0); 2754 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2755 bs = g_bs; 2756 2757 /* Create blob */ 2758 spdk_blob_opts_init(&opts); 2759 opts.num_clusters = 10; 2760 2761 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2762 poll_threads(); 2763 CU_ASSERT(g_bserrno == 0); 2764 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2765 blobid = g_blobid; 2766 2767 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2768 poll_threads(); 2769 CU_ASSERT(g_bserrno == 0); 2770 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2771 blob = g_blob; 2772 2773 /* Create snapshot */ 2774 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 2775 poll_threads(); 2776 CU_ASSERT(g_bserrno == 0); 2777 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2778 snapshotid = g_blobid; 2779 2780 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 2781 poll_threads(); 2782 CU_ASSERT(g_bserrno == 0); 2783 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2784 snapshot = g_blob; 2785 2786 /* Set SNAPSHOT_PENDING_REMOVAL xattr */ 2787 snapshot->md_ro = false; 2788 rc = _spdk_blob_set_xattr(snapshot, SNAPSHOT_PENDING_REMOVAL, &blobid, sizeof(spdk_blob_id), true); 2789 CU_ASSERT(rc == 0); 2790 snapshot->md_ro = true; 2791 2792 spdk_blob_close(snapshot, blob_op_complete, NULL); 2793 poll_threads(); 2794 CU_ASSERT(g_bserrno == 0); 2795 2796 spdk_blob_close(blob, blob_op_complete, NULL); 2797 poll_threads(); 2798 CU_ASSERT(g_bserrno == 0); 2799 2800 /* Reload blobstore */ 2801 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2802 poll_threads(); 2803 CU_ASSERT(g_bserrno == 0); 2804 g_bs = NULL; 2805 2806 dev = init_dev(); 2807 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2808 poll_threads(); 2809 CU_ASSERT(g_bserrno == 0); 2810 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2811 bs = g_bs; 2812 2813 /* Snapshot should not be removed as blob is still pointing to it */ 2814 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 2815 poll_threads(); 2816 CU_ASSERT(g_bserrno == 0); 2817 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2818 snapshot = g_blob; 2819 2820 /* SNAPSHOT_PENDING_REMOVAL xattr should be removed during load */ 2821 rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_PENDING_REMOVAL, &value, &value_len); 2822 CU_ASSERT(rc != 0); 2823 2824 /* Set SNAPSHOT_PENDING_REMOVAL xattr again */ 2825 snapshot->md_ro = false; 2826 rc = _spdk_blob_set_xattr(snapshot, SNAPSHOT_PENDING_REMOVAL, &blobid, sizeof(spdk_blob_id), true); 2827 CU_ASSERT(rc == 0); 2828 snapshot->md_ro = true; 2829 2830 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2831 poll_threads(); 2832 CU_ASSERT(g_bserrno == 0); 2833 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2834 blob = g_blob; 2835 2836 /* Remove parent_id from blob by removing BLOB_SNAPSHOT xattr */ 2837 _spdk_blob_remove_xattr(blob, BLOB_SNAPSHOT, true); 2838 2839 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2840 poll_threads(); 2841 CU_ASSERT(g_bserrno == 0); 2842 2843 spdk_blob_close(snapshot, blob_op_complete, NULL); 2844 poll_threads(); 2845 CU_ASSERT(g_bserrno == 0); 2846 2847 spdk_blob_close(blob, blob_op_complete, NULL); 2848 poll_threads(); 2849 CU_ASSERT(g_bserrno == 0); 2850 2851 /* Reload blobstore */ 2852 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2853 poll_threads(); 2854 CU_ASSERT(g_bserrno == 0); 2855 g_bs = NULL; 2856 2857 dev = init_dev(); 2858 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2859 poll_threads(); 2860 CU_ASSERT(g_bserrno == 0); 2861 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2862 bs = g_bs; 2863 2864 /* Snapshot should be removed as blob is not pointing to it anymore */ 2865 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 2866 poll_threads(); 2867 CU_ASSERT(g_bserrno != 0); 2868 2869 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2870 poll_threads(); 2871 CU_ASSERT(g_bserrno == 0); 2872 g_bs = NULL; 2873 } 2874 2875 static void 2876 bs_load_custom_cluster_size(void) 2877 { 2878 struct spdk_bs_dev *dev; 2879 struct spdk_bs_super_block *super_block; 2880 struct spdk_bs_opts opts; 2881 uint32_t custom_cluster_size = 4194304; /* 4MiB */ 2882 uint32_t cluster_sz; 2883 uint64_t total_clusters; 2884 2885 dev = init_dev(); 2886 spdk_bs_opts_init(&opts); 2887 opts.cluster_sz = custom_cluster_size; 2888 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2889 2890 /* Initialize a new blob store */ 2891 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2892 poll_threads(); 2893 CU_ASSERT(g_bserrno == 0); 2894 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2895 cluster_sz = g_bs->cluster_sz; 2896 total_clusters = g_bs->total_clusters; 2897 2898 /* Unload the blob store */ 2899 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2900 poll_threads(); 2901 CU_ASSERT(g_bserrno == 0); 2902 g_bs = NULL; 2903 g_blob = NULL; 2904 g_blobid = 0; 2905 2906 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2907 CU_ASSERT(super_block->clean == 1); 2908 2909 /* Load an existing blob store */ 2910 dev = init_dev(); 2911 spdk_bs_opts_init(&opts); 2912 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2913 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2914 poll_threads(); 2915 CU_ASSERT(g_bserrno == 0); 2916 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2917 /* Compare cluster size and number to one after initialization */ 2918 CU_ASSERT(cluster_sz == g_bs->cluster_sz); 2919 CU_ASSERT(total_clusters == g_bs->total_clusters); 2920 2921 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2922 CU_ASSERT(super_block->clean == 1); 2923 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2924 2925 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2926 poll_threads(); 2927 CU_ASSERT(g_bserrno == 0); 2928 CU_ASSERT(super_block->clean == 1); 2929 g_bs = NULL; 2930 } 2931 2932 static void 2933 bs_type(void) 2934 { 2935 struct spdk_bs_dev *dev; 2936 struct spdk_bs_opts opts; 2937 2938 dev = init_dev(); 2939 spdk_bs_opts_init(&opts); 2940 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2941 2942 /* Initialize a new blob store */ 2943 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2944 poll_threads(); 2945 CU_ASSERT(g_bserrno == 0); 2946 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2947 2948 /* Unload the blob store */ 2949 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2950 poll_threads(); 2951 CU_ASSERT(g_bserrno == 0); 2952 g_bs = NULL; 2953 g_blob = NULL; 2954 g_blobid = 0; 2955 2956 /* Load non existing blobstore type */ 2957 dev = init_dev(); 2958 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 2959 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2960 poll_threads(); 2961 CU_ASSERT(g_bserrno != 0); 2962 2963 /* Load with empty blobstore type */ 2964 dev = init_dev(); 2965 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2966 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2967 poll_threads(); 2968 CU_ASSERT(g_bserrno == 0); 2969 2970 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2971 poll_threads(); 2972 CU_ASSERT(g_bserrno == 0); 2973 g_bs = NULL; 2974 2975 /* Initialize a new blob store with empty bstype */ 2976 dev = init_dev(); 2977 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2978 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2979 poll_threads(); 2980 CU_ASSERT(g_bserrno == 0); 2981 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2982 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 /* Load non existing blobstore type */ 2989 dev = init_dev(); 2990 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 2991 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2992 poll_threads(); 2993 CU_ASSERT(g_bserrno != 0); 2994 2995 /* Load with empty blobstore type */ 2996 dev = init_dev(); 2997 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2998 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2999 poll_threads(); 3000 CU_ASSERT(g_bserrno == 0); 3001 3002 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3003 poll_threads(); 3004 CU_ASSERT(g_bserrno == 0); 3005 g_bs = NULL; 3006 } 3007 3008 static void 3009 bs_super_block(void) 3010 { 3011 struct spdk_bs_dev *dev; 3012 struct spdk_bs_super_block *super_block; 3013 struct spdk_bs_opts opts; 3014 struct spdk_bs_super_block_ver1 super_block_v1; 3015 3016 dev = init_dev(); 3017 spdk_bs_opts_init(&opts); 3018 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3019 3020 /* Initialize a new blob store */ 3021 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3022 poll_threads(); 3023 CU_ASSERT(g_bserrno == 0); 3024 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3025 3026 /* Unload the blob store */ 3027 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3028 poll_threads(); 3029 CU_ASSERT(g_bserrno == 0); 3030 g_bs = NULL; 3031 g_blob = NULL; 3032 g_blobid = 0; 3033 3034 /* Load an existing blob store with version newer than supported */ 3035 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 3036 super_block->version++; 3037 3038 dev = init_dev(); 3039 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 3040 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3041 poll_threads(); 3042 CU_ASSERT(g_bserrno != 0); 3043 3044 /* Create a new blob store with super block version 1 */ 3045 dev = init_dev(); 3046 super_block_v1.version = 1; 3047 memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 3048 super_block_v1.length = 0x1000; 3049 super_block_v1.clean = 1; 3050 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 3051 super_block_v1.cluster_size = 0x100000; 3052 super_block_v1.used_page_mask_start = 0x01; 3053 super_block_v1.used_page_mask_len = 0x01; 3054 super_block_v1.used_cluster_mask_start = 0x02; 3055 super_block_v1.used_cluster_mask_len = 0x01; 3056 super_block_v1.md_start = 0x03; 3057 super_block_v1.md_len = 0x40; 3058 memset(super_block_v1.reserved, 0, 4036); 3059 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 3060 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 3061 3062 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 3063 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3064 poll_threads(); 3065 CU_ASSERT(g_bserrno == 0); 3066 3067 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3068 poll_threads(); 3069 CU_ASSERT(g_bserrno == 0); 3070 g_bs = NULL; 3071 } 3072 3073 /* 3074 * Create a blobstore and then unload it. 3075 */ 3076 static void 3077 bs_unload(void) 3078 { 3079 struct spdk_bs_dev *dev; 3080 struct spdk_blob_store *bs; 3081 spdk_blob_id blobid; 3082 struct spdk_blob *blob; 3083 3084 dev = init_dev(); 3085 3086 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3087 poll_threads(); 3088 CU_ASSERT(g_bserrno == 0); 3089 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3090 bs = g_bs; 3091 3092 /* Create a blob and open it. */ 3093 g_bserrno = -1; 3094 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 3095 poll_threads(); 3096 CU_ASSERT(g_bserrno == 0); 3097 CU_ASSERT(g_blobid > 0); 3098 blobid = g_blobid; 3099 3100 g_bserrno = -1; 3101 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3102 poll_threads(); 3103 CU_ASSERT(g_bserrno == 0); 3104 CU_ASSERT(g_blob != NULL); 3105 blob = g_blob; 3106 3107 /* Try to unload blobstore, should fail with open blob */ 3108 g_bserrno = -1; 3109 spdk_bs_unload(bs, bs_op_complete, NULL); 3110 poll_threads(); 3111 CU_ASSERT(g_bserrno == -EBUSY); 3112 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3113 3114 /* Close the blob, then successfully unload blobstore */ 3115 g_bserrno = -1; 3116 spdk_blob_close(blob, blob_op_complete, NULL); 3117 poll_threads(); 3118 CU_ASSERT(g_bserrno == 0); 3119 3120 g_bserrno = -1; 3121 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3122 poll_threads(); 3123 CU_ASSERT(g_bserrno == 0); 3124 g_bs = NULL; 3125 } 3126 3127 /* 3128 * Create a blobstore with a cluster size different than the default, and ensure it is 3129 * persisted. 3130 */ 3131 static void 3132 bs_cluster_sz(void) 3133 { 3134 struct spdk_bs_dev *dev; 3135 struct spdk_bs_opts opts; 3136 uint32_t cluster_sz; 3137 3138 /* Set cluster size to zero */ 3139 dev = init_dev(); 3140 spdk_bs_opts_init(&opts); 3141 opts.cluster_sz = 0; 3142 3143 /* Initialize a new blob store */ 3144 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3145 poll_threads(); 3146 CU_ASSERT(g_bserrno == -EINVAL); 3147 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 3148 3149 /* 3150 * Set cluster size to blobstore page size, 3151 * to work it is required to be at least twice the blobstore page size. 3152 */ 3153 dev = init_dev(); 3154 spdk_bs_opts_init(&opts); 3155 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 3156 3157 /* Initialize a new blob store */ 3158 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3159 poll_threads(); 3160 CU_ASSERT(g_bserrno == -ENOMEM); 3161 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 3162 3163 /* 3164 * Set cluster size to lower than page size, 3165 * to work it is required to be at least twice the blobstore page size. 3166 */ 3167 dev = init_dev(); 3168 spdk_bs_opts_init(&opts); 3169 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 3170 3171 /* Initialize a new blob store */ 3172 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3173 poll_threads(); 3174 CU_ASSERT(g_bserrno == -EINVAL); 3175 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 3176 3177 /* Set cluster size to twice the default */ 3178 dev = init_dev(); 3179 spdk_bs_opts_init(&opts); 3180 opts.cluster_sz *= 2; 3181 cluster_sz = opts.cluster_sz; 3182 3183 /* Initialize a new blob store */ 3184 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3185 poll_threads(); 3186 CU_ASSERT(g_bserrno == 0); 3187 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3188 3189 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 3190 3191 /* Unload the blob store */ 3192 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3193 poll_threads(); 3194 CU_ASSERT(g_bserrno == 0); 3195 g_bs = NULL; 3196 g_blob = NULL; 3197 g_blobid = 0; 3198 3199 dev = init_dev(); 3200 /* Load an existing blob store */ 3201 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3202 poll_threads(); 3203 CU_ASSERT(g_bserrno == 0); 3204 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3205 3206 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 3207 3208 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3209 poll_threads(); 3210 CU_ASSERT(g_bserrno == 0); 3211 g_bs = NULL; 3212 } 3213 3214 /* 3215 * Create a blobstore, reload it and ensure total usable cluster count 3216 * stays the same. 3217 */ 3218 static void 3219 bs_usable_clusters(void) 3220 { 3221 struct spdk_bs_dev *dev; 3222 struct spdk_bs_opts opts; 3223 uint32_t clusters; 3224 int i; 3225 3226 /* Init blobstore */ 3227 dev = init_dev(); 3228 spdk_bs_opts_init(&opts); 3229 3230 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3231 poll_threads(); 3232 CU_ASSERT(g_bserrno == 0); 3233 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3234 3235 clusters = spdk_bs_total_data_cluster_count(g_bs); 3236 3237 /* Unload the blob store */ 3238 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3239 poll_threads(); 3240 CU_ASSERT(g_bserrno == 0); 3241 g_bs = NULL; 3242 3243 dev = init_dev(); 3244 /* Load an existing blob store */ 3245 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3246 poll_threads(); 3247 CU_ASSERT(g_bserrno == 0); 3248 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3249 3250 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 3251 3252 /* Create and resize blobs to make sure that useable cluster count won't change */ 3253 for (i = 0; i < 4; i++) { 3254 g_bserrno = -1; 3255 g_blobid = SPDK_BLOBID_INVALID; 3256 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3257 poll_threads(); 3258 CU_ASSERT(g_bserrno == 0); 3259 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3260 3261 g_bserrno = -1; 3262 g_blob = NULL; 3263 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 3264 poll_threads(); 3265 CU_ASSERT(g_bserrno == 0); 3266 CU_ASSERT(g_blob != NULL); 3267 3268 spdk_blob_resize(g_blob, 10, blob_op_complete, NULL); 3269 poll_threads(); 3270 CU_ASSERT(g_bserrno == 0); 3271 3272 g_bserrno = -1; 3273 spdk_blob_close(g_blob, blob_op_complete, NULL); 3274 poll_threads(); 3275 CU_ASSERT(g_bserrno == 0); 3276 3277 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 3278 } 3279 3280 /* Reload the blob store to make sure that nothing changed */ 3281 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3282 poll_threads(); 3283 CU_ASSERT(g_bserrno == 0); 3284 g_bs = NULL; 3285 3286 dev = init_dev(); 3287 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3288 poll_threads(); 3289 CU_ASSERT(g_bserrno == 0); 3290 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3291 3292 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 3293 3294 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3295 poll_threads(); 3296 CU_ASSERT(g_bserrno == 0); 3297 g_bs = NULL; 3298 } 3299 3300 /* 3301 * Test resizing of the metadata blob. This requires creating enough blobs 3302 * so that one cluster is not enough to fit the metadata for those blobs. 3303 * To induce this condition to happen more quickly, we reduce the cluster 3304 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 3305 */ 3306 static void 3307 bs_resize_md(void) 3308 { 3309 const int CLUSTER_PAGE_COUNT = 4; 3310 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 3311 struct spdk_bs_dev *dev; 3312 struct spdk_bs_opts opts; 3313 uint32_t cluster_sz; 3314 spdk_blob_id blobids[NUM_BLOBS]; 3315 int i; 3316 3317 3318 dev = init_dev(); 3319 spdk_bs_opts_init(&opts); 3320 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 3321 cluster_sz = opts.cluster_sz; 3322 3323 /* Initialize a new blob store */ 3324 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3325 poll_threads(); 3326 CU_ASSERT(g_bserrno == 0); 3327 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3328 3329 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 3330 3331 for (i = 0; i < NUM_BLOBS; i++) { 3332 g_bserrno = -1; 3333 g_blobid = SPDK_BLOBID_INVALID; 3334 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3335 poll_threads(); 3336 CU_ASSERT(g_bserrno == 0); 3337 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3338 blobids[i] = g_blobid; 3339 } 3340 3341 /* Unload the blob store */ 3342 g_bserrno = -1; 3343 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3344 poll_threads(); 3345 CU_ASSERT(g_bserrno == 0); 3346 3347 /* Load an existing blob store */ 3348 g_bserrno = -1; 3349 g_bs = NULL; 3350 dev = init_dev(); 3351 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3352 poll_threads(); 3353 CU_ASSERT(g_bserrno == 0); 3354 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3355 3356 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 3357 3358 for (i = 0; i < NUM_BLOBS; i++) { 3359 g_bserrno = -1; 3360 g_blob = NULL; 3361 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 3362 poll_threads(); 3363 CU_ASSERT(g_bserrno == 0); 3364 CU_ASSERT(g_blob != NULL); 3365 g_bserrno = -1; 3366 spdk_blob_close(g_blob, blob_op_complete, NULL); 3367 poll_threads(); 3368 CU_ASSERT(g_bserrno == 0); 3369 } 3370 3371 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3372 poll_threads(); 3373 CU_ASSERT(g_bserrno == 0); 3374 g_bs = NULL; 3375 } 3376 3377 static void 3378 bs_destroy(void) 3379 { 3380 struct spdk_bs_dev *dev; 3381 struct spdk_bs_opts opts; 3382 3383 /* Initialize a new blob store */ 3384 dev = init_dev(); 3385 spdk_bs_opts_init(&opts); 3386 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3387 poll_threads(); 3388 CU_ASSERT(g_bserrno == 0); 3389 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3390 3391 /* Destroy the blob store */ 3392 g_bserrno = -1; 3393 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 3394 poll_threads(); 3395 CU_ASSERT(g_bserrno == 0); 3396 3397 /* Loading an non-existent blob store should fail. */ 3398 g_bs = NULL; 3399 dev = init_dev(); 3400 3401 g_bserrno = 0; 3402 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3403 poll_threads(); 3404 CU_ASSERT(g_bserrno != 0); 3405 } 3406 3407 /* Try to hit all of the corner cases associated with serializing 3408 * a blob to disk 3409 */ 3410 static void 3411 blob_serialize(void) 3412 { 3413 struct spdk_bs_dev *dev; 3414 struct spdk_bs_opts opts; 3415 struct spdk_blob_store *bs; 3416 spdk_blob_id blobid[2]; 3417 struct spdk_blob *blob[2]; 3418 uint64_t i; 3419 char *value; 3420 int rc; 3421 3422 dev = init_dev(); 3423 3424 /* Initialize a new blobstore with very small clusters */ 3425 spdk_bs_opts_init(&opts); 3426 opts.cluster_sz = dev->blocklen * 8; 3427 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3428 poll_threads(); 3429 CU_ASSERT(g_bserrno == 0); 3430 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3431 bs = g_bs; 3432 3433 /* Create and open two blobs */ 3434 for (i = 0; i < 2; i++) { 3435 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 3436 poll_threads(); 3437 CU_ASSERT(g_bserrno == 0); 3438 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3439 blobid[i] = g_blobid; 3440 3441 /* Open a blob */ 3442 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 3443 poll_threads(); 3444 CU_ASSERT(g_bserrno == 0); 3445 CU_ASSERT(g_blob != NULL); 3446 blob[i] = g_blob; 3447 3448 /* Set a fairly large xattr on both blobs to eat up 3449 * metadata space 3450 */ 3451 value = calloc(dev->blocklen - 64, sizeof(char)); 3452 SPDK_CU_ASSERT_FATAL(value != NULL); 3453 memset(value, i, dev->blocklen / 2); 3454 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 3455 CU_ASSERT(rc == 0); 3456 free(value); 3457 } 3458 3459 /* Resize the blobs, alternating 1 cluster at a time. 3460 * This thwarts run length encoding and will cause spill 3461 * over of the extents. 3462 */ 3463 for (i = 0; i < 6; i++) { 3464 spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL); 3465 poll_threads(); 3466 CU_ASSERT(g_bserrno == 0); 3467 } 3468 3469 for (i = 0; i < 2; i++) { 3470 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 3471 poll_threads(); 3472 CU_ASSERT(g_bserrno == 0); 3473 } 3474 3475 /* Close the blobs */ 3476 for (i = 0; i < 2; i++) { 3477 spdk_blob_close(blob[i], blob_op_complete, NULL); 3478 poll_threads(); 3479 CU_ASSERT(g_bserrno == 0); 3480 } 3481 3482 /* Unload the blobstore */ 3483 spdk_bs_unload(bs, bs_op_complete, NULL); 3484 poll_threads(); 3485 CU_ASSERT(g_bserrno == 0); 3486 g_bs = NULL; 3487 g_blob = NULL; 3488 g_blobid = 0; 3489 bs = NULL; 3490 3491 dev = init_dev(); 3492 /* Load an existing blob store */ 3493 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3494 poll_threads(); 3495 CU_ASSERT(g_bserrno == 0); 3496 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3497 bs = g_bs; 3498 3499 for (i = 0; i < 2; i++) { 3500 blob[i] = NULL; 3501 3502 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 3503 poll_threads(); 3504 CU_ASSERT(g_bserrno == 0); 3505 CU_ASSERT(g_blob != NULL); 3506 blob[i] = g_blob; 3507 3508 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 3509 3510 spdk_blob_close(blob[i], blob_op_complete, NULL); 3511 poll_threads(); 3512 CU_ASSERT(g_bserrno == 0); 3513 } 3514 3515 spdk_bs_unload(bs, bs_op_complete, NULL); 3516 poll_threads(); 3517 CU_ASSERT(g_bserrno == 0); 3518 g_bs = NULL; 3519 } 3520 3521 static void 3522 blob_crc(void) 3523 { 3524 struct spdk_blob_store *bs; 3525 struct spdk_bs_dev *dev; 3526 struct spdk_blob *blob; 3527 spdk_blob_id blobid; 3528 uint32_t page_num; 3529 int index; 3530 struct spdk_blob_md_page *page; 3531 3532 dev = init_dev(); 3533 3534 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3535 poll_threads(); 3536 CU_ASSERT(g_bserrno == 0); 3537 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3538 bs = g_bs; 3539 3540 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 3541 poll_threads(); 3542 CU_ASSERT(g_bserrno == 0); 3543 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3544 blobid = g_blobid; 3545 3546 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3547 poll_threads(); 3548 CU_ASSERT(g_bserrno == 0); 3549 CU_ASSERT(g_blob != NULL); 3550 blob = g_blob; 3551 3552 spdk_blob_close(blob, blob_op_complete, NULL); 3553 poll_threads(); 3554 CU_ASSERT(g_bserrno == 0); 3555 3556 page_num = _spdk_bs_blobid_to_page(blobid); 3557 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 3558 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3559 page->crc = 0; 3560 3561 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3562 poll_threads(); 3563 CU_ASSERT(g_bserrno == -EINVAL); 3564 CU_ASSERT(g_blob == NULL); 3565 g_bserrno = 0; 3566 3567 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3568 poll_threads(); 3569 CU_ASSERT(g_bserrno == -EINVAL); 3570 3571 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3572 poll_threads(); 3573 CU_ASSERT(g_bserrno == 0); 3574 g_bs = NULL; 3575 } 3576 3577 static void 3578 super_block_crc(void) 3579 { 3580 struct spdk_bs_dev *dev; 3581 struct spdk_bs_super_block *super_block; 3582 struct spdk_bs_opts opts; 3583 3584 dev = init_dev(); 3585 spdk_bs_opts_init(&opts); 3586 3587 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3588 poll_threads(); 3589 CU_ASSERT(g_bserrno == 0); 3590 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3591 3592 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3593 poll_threads(); 3594 CU_ASSERT(g_bserrno == 0); 3595 g_bs = NULL; 3596 3597 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 3598 super_block->crc = 0; 3599 dev = init_dev(); 3600 3601 /* Load an existing blob store */ 3602 g_bserrno = 0; 3603 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3604 poll_threads(); 3605 CU_ASSERT(g_bserrno == -EILSEQ); 3606 } 3607 3608 /* For blob dirty shutdown test case we do the following sub-test cases: 3609 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we 3610 * dirty shutdown and reload the blob store and verify the xattrs. 3611 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 3612 * reload the blob store and verify the clusters number. 3613 * 3 Create the second blob and then dirty shutdown, reload the blob store 3614 * and verify the second blob. 3615 * 4 Delete the second blob and then dirty shutdown, reload the blob store 3616 * and verify the second blob is invalid. 3617 * 5 Create the second blob again and also create the third blob, modify the 3618 * md of second blob which makes the md invalid, and then dirty shutdown, 3619 * reload the blob store verify the second blob, it should invalid and also 3620 * verify the third blob, it should correct. 3621 */ 3622 static void 3623 blob_dirty_shutdown(void) 3624 { 3625 int rc; 3626 int index; 3627 struct spdk_bs_dev *dev; 3628 spdk_blob_id blobid1, blobid2, blobid3; 3629 struct spdk_blob *blob; 3630 uint64_t length; 3631 uint64_t free_clusters; 3632 const void *value; 3633 size_t value_len; 3634 uint32_t page_num; 3635 struct spdk_blob_md_page *page; 3636 struct spdk_bs_opts opts; 3637 3638 dev = init_dev(); 3639 spdk_bs_opts_init(&opts); 3640 /* Initialize a new blob store */ 3641 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3642 poll_threads(); 3643 CU_ASSERT(g_bserrno == 0); 3644 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3645 3646 /* Create first blob */ 3647 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3648 poll_threads(); 3649 CU_ASSERT(g_bserrno == 0); 3650 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3651 blobid1 = g_blobid; 3652 3653 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3654 poll_threads(); 3655 CU_ASSERT(g_bserrno == 0); 3656 CU_ASSERT(g_blob != NULL); 3657 blob = g_blob; 3658 3659 /* Set some xattrs */ 3660 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 3661 CU_ASSERT(rc == 0); 3662 3663 length = 2345; 3664 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3665 CU_ASSERT(rc == 0); 3666 3667 /* Resize the blob */ 3668 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3669 poll_threads(); 3670 CU_ASSERT(g_bserrno == 0); 3671 3672 /* Set the blob as the super blob */ 3673 spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL); 3674 poll_threads(); 3675 CU_ASSERT(g_bserrno == 0); 3676 3677 free_clusters = spdk_bs_free_cluster_count(g_bs); 3678 3679 spdk_blob_close(blob, blob_op_complete, NULL); 3680 poll_threads(); 3681 CU_ASSERT(g_bserrno == 0); 3682 blob = NULL; 3683 g_blob = NULL; 3684 g_blobid = SPDK_BLOBID_INVALID; 3685 3686 /* Dirty shutdown */ 3687 _spdk_bs_free(g_bs); 3688 3689 /* reload blobstore */ 3690 dev = init_dev(); 3691 spdk_bs_opts_init(&opts); 3692 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3693 poll_threads(); 3694 CU_ASSERT(g_bserrno == 0); 3695 3696 /* Get the super blob */ 3697 spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL); 3698 poll_threads(); 3699 CU_ASSERT(g_bserrno == 0); 3700 CU_ASSERT(blobid1 == g_blobid); 3701 3702 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3703 poll_threads(); 3704 CU_ASSERT(g_bserrno == 0); 3705 CU_ASSERT(g_blob != NULL); 3706 blob = g_blob; 3707 3708 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3709 3710 /* Get the xattrs */ 3711 value = NULL; 3712 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3713 CU_ASSERT(rc == 0); 3714 SPDK_CU_ASSERT_FATAL(value != NULL); 3715 CU_ASSERT(*(uint64_t *)value == length); 3716 CU_ASSERT(value_len == 8); 3717 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3718 3719 /* Resize the blob */ 3720 spdk_blob_resize(blob, 20, blob_op_complete, NULL); 3721 poll_threads(); 3722 CU_ASSERT(g_bserrno == 0); 3723 3724 free_clusters = spdk_bs_free_cluster_count(g_bs); 3725 3726 spdk_blob_close(blob, blob_op_complete, NULL); 3727 poll_threads(); 3728 CU_ASSERT(g_bserrno == 0); 3729 blob = NULL; 3730 g_blob = NULL; 3731 g_blobid = SPDK_BLOBID_INVALID; 3732 3733 /* Dirty shutdown */ 3734 _spdk_bs_free(g_bs); 3735 3736 /* reload the blobstore */ 3737 dev = init_dev(); 3738 spdk_bs_opts_init(&opts); 3739 /* Load an existing blob store */ 3740 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3741 poll_threads(); 3742 CU_ASSERT(g_bserrno == 0); 3743 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3744 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3745 poll_threads(); 3746 CU_ASSERT(g_bserrno == 0); 3747 CU_ASSERT(g_blob != NULL); 3748 blob = g_blob; 3749 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 3750 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3751 3752 spdk_blob_close(blob, blob_op_complete, NULL); 3753 poll_threads(); 3754 CU_ASSERT(g_bserrno == 0); 3755 blob = NULL; 3756 g_blob = NULL; 3757 g_blobid = SPDK_BLOBID_INVALID; 3758 3759 /* Create second blob */ 3760 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3761 poll_threads(); 3762 CU_ASSERT(g_bserrno == 0); 3763 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3764 blobid2 = g_blobid; 3765 3766 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3767 poll_threads(); 3768 CU_ASSERT(g_bserrno == 0); 3769 CU_ASSERT(g_blob != NULL); 3770 blob = g_blob; 3771 3772 /* Set some xattrs */ 3773 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3774 CU_ASSERT(rc == 0); 3775 3776 length = 5432; 3777 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3778 CU_ASSERT(rc == 0); 3779 3780 /* Resize the blob */ 3781 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3782 poll_threads(); 3783 CU_ASSERT(g_bserrno == 0); 3784 3785 free_clusters = spdk_bs_free_cluster_count(g_bs); 3786 3787 spdk_blob_close(blob, blob_op_complete, NULL); 3788 poll_threads(); 3789 CU_ASSERT(g_bserrno == 0); 3790 blob = NULL; 3791 g_blob = NULL; 3792 g_blobid = SPDK_BLOBID_INVALID; 3793 3794 /* Dirty shutdown */ 3795 _spdk_bs_free(g_bs); 3796 3797 /* reload the blobstore */ 3798 dev = init_dev(); 3799 spdk_bs_opts_init(&opts); 3800 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3801 poll_threads(); 3802 CU_ASSERT(g_bserrno == 0); 3803 3804 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3805 poll_threads(); 3806 CU_ASSERT(g_bserrno == 0); 3807 CU_ASSERT(g_blob != NULL); 3808 blob = g_blob; 3809 3810 /* Get the xattrs */ 3811 value = NULL; 3812 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3813 CU_ASSERT(rc == 0); 3814 SPDK_CU_ASSERT_FATAL(value != NULL); 3815 CU_ASSERT(*(uint64_t *)value == length); 3816 CU_ASSERT(value_len == 8); 3817 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3818 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3819 3820 spdk_blob_close(blob, blob_op_complete, NULL); 3821 poll_threads(); 3822 CU_ASSERT(g_bserrno == 0); 3823 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 3824 poll_threads(); 3825 CU_ASSERT(g_bserrno == 0); 3826 3827 free_clusters = spdk_bs_free_cluster_count(g_bs); 3828 3829 /* Dirty shutdown */ 3830 _spdk_bs_free(g_bs); 3831 /* reload the blobstore */ 3832 dev = init_dev(); 3833 spdk_bs_opts_init(&opts); 3834 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3835 poll_threads(); 3836 CU_ASSERT(g_bserrno == 0); 3837 3838 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3839 poll_threads(); 3840 CU_ASSERT(g_bserrno != 0); 3841 CU_ASSERT(g_blob == NULL); 3842 3843 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 3844 poll_threads(); 3845 CU_ASSERT(g_bserrno == 0); 3846 CU_ASSERT(g_blob != NULL); 3847 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3848 spdk_blob_close(g_blob, blob_op_complete, NULL); 3849 poll_threads(); 3850 CU_ASSERT(g_bserrno == 0); 3851 3852 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3853 poll_threads(); 3854 CU_ASSERT(g_bserrno == 0); 3855 g_bs = NULL; 3856 3857 /* reload the blobstore */ 3858 dev = init_dev(); 3859 spdk_bs_opts_init(&opts); 3860 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3861 poll_threads(); 3862 CU_ASSERT(g_bserrno == 0); 3863 3864 /* Create second blob */ 3865 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3866 poll_threads(); 3867 CU_ASSERT(g_bserrno == 0); 3868 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3869 blobid2 = g_blobid; 3870 3871 /* Create third blob */ 3872 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3873 poll_threads(); 3874 CU_ASSERT(g_bserrno == 0); 3875 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3876 blobid3 = g_blobid; 3877 3878 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3879 poll_threads(); 3880 CU_ASSERT(g_bserrno == 0); 3881 CU_ASSERT(g_blob != NULL); 3882 blob = g_blob; 3883 3884 /* Set some xattrs for second blob */ 3885 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3886 CU_ASSERT(rc == 0); 3887 3888 length = 5432; 3889 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3890 CU_ASSERT(rc == 0); 3891 3892 spdk_blob_close(blob, blob_op_complete, NULL); 3893 poll_threads(); 3894 CU_ASSERT(g_bserrno == 0); 3895 blob = NULL; 3896 g_blob = NULL; 3897 g_blobid = SPDK_BLOBID_INVALID; 3898 3899 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 3900 poll_threads(); 3901 CU_ASSERT(g_bserrno == 0); 3902 CU_ASSERT(g_blob != NULL); 3903 blob = g_blob; 3904 3905 /* Set some xattrs for third blob */ 3906 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 3907 CU_ASSERT(rc == 0); 3908 3909 length = 5432; 3910 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3911 CU_ASSERT(rc == 0); 3912 3913 spdk_blob_close(blob, blob_op_complete, NULL); 3914 poll_threads(); 3915 CU_ASSERT(g_bserrno == 0); 3916 blob = NULL; 3917 g_blob = NULL; 3918 g_blobid = SPDK_BLOBID_INVALID; 3919 3920 /* Mark second blob as invalid */ 3921 page_num = _spdk_bs_blobid_to_page(blobid2); 3922 3923 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 3924 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3925 page->sequence_num = 1; 3926 page->crc = _spdk_blob_md_page_calc_crc(page); 3927 3928 free_clusters = spdk_bs_free_cluster_count(g_bs); 3929 3930 /* Dirty shutdown */ 3931 _spdk_bs_free(g_bs); 3932 /* reload the blobstore */ 3933 dev = init_dev(); 3934 spdk_bs_opts_init(&opts); 3935 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3936 poll_threads(); 3937 CU_ASSERT(g_bserrno == 0); 3938 3939 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 3940 poll_threads(); 3941 CU_ASSERT(g_bserrno != 0); 3942 CU_ASSERT(g_blob == NULL); 3943 3944 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 3945 poll_threads(); 3946 CU_ASSERT(g_bserrno == 0); 3947 CU_ASSERT(g_blob != NULL); 3948 blob = g_blob; 3949 3950 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 3951 3952 spdk_blob_close(blob, blob_op_complete, NULL); 3953 poll_threads(); 3954 CU_ASSERT(g_bserrno == 0); 3955 blob = NULL; 3956 g_blob = NULL; 3957 g_blobid = SPDK_BLOBID_INVALID; 3958 3959 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3960 poll_threads(); 3961 CU_ASSERT(g_bserrno == 0); 3962 g_bs = NULL; 3963 } 3964 3965 static void 3966 blob_flags(void) 3967 { 3968 struct spdk_bs_dev *dev; 3969 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 3970 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 3971 struct spdk_bs_opts opts; 3972 int rc; 3973 3974 dev = init_dev(); 3975 spdk_bs_opts_init(&opts); 3976 3977 /* Initialize a new blob store */ 3978 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3979 poll_threads(); 3980 CU_ASSERT(g_bserrno == 0); 3981 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3982 3983 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 3984 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3985 poll_threads(); 3986 CU_ASSERT(g_bserrno == 0); 3987 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3988 blobid_invalid = g_blobid; 3989 3990 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3991 poll_threads(); 3992 CU_ASSERT(g_bserrno == 0); 3993 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3994 blobid_data_ro = g_blobid; 3995 3996 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3997 poll_threads(); 3998 CU_ASSERT(g_bserrno == 0); 3999 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4000 blobid_md_ro = g_blobid; 4001 4002 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 4003 poll_threads(); 4004 CU_ASSERT(g_bserrno == 0); 4005 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4006 blob_invalid = g_blob; 4007 4008 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 4009 poll_threads(); 4010 CU_ASSERT(g_bserrno == 0); 4011 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4012 blob_data_ro = g_blob; 4013 4014 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 4015 poll_threads(); 4016 CU_ASSERT(g_bserrno == 0); 4017 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4018 blob_md_ro = g_blob; 4019 4020 /* Change the size of blob_data_ro to check if flags are serialized 4021 * when blob has non zero number of extents */ 4022 spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL); 4023 poll_threads(); 4024 CU_ASSERT(g_bserrno == 0); 4025 4026 /* Set the xattr to check if flags are serialized 4027 * when blob has non zero number of xattrs */ 4028 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 4029 CU_ASSERT(rc == 0); 4030 4031 blob_invalid->invalid_flags = (1ULL << 63); 4032 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 4033 blob_data_ro->data_ro_flags = (1ULL << 62); 4034 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 4035 blob_md_ro->md_ro_flags = (1ULL << 61); 4036 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 4037 4038 g_bserrno = -1; 4039 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 4040 poll_threads(); 4041 CU_ASSERT(g_bserrno == 0); 4042 g_bserrno = -1; 4043 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 4044 poll_threads(); 4045 CU_ASSERT(g_bserrno == 0); 4046 g_bserrno = -1; 4047 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 4048 poll_threads(); 4049 CU_ASSERT(g_bserrno == 0); 4050 4051 g_bserrno = -1; 4052 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 4053 poll_threads(); 4054 CU_ASSERT(g_bserrno == 0); 4055 blob_invalid = NULL; 4056 g_bserrno = -1; 4057 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 4058 poll_threads(); 4059 CU_ASSERT(g_bserrno == 0); 4060 blob_data_ro = NULL; 4061 g_bserrno = -1; 4062 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 4063 poll_threads(); 4064 CU_ASSERT(g_bserrno == 0); 4065 blob_md_ro = NULL; 4066 4067 g_blob = NULL; 4068 g_blobid = SPDK_BLOBID_INVALID; 4069 4070 /* Unload the blob store */ 4071 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4072 poll_threads(); 4073 CU_ASSERT(g_bserrno == 0); 4074 g_bs = NULL; 4075 4076 /* Load an existing blob store */ 4077 dev = init_dev(); 4078 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4079 poll_threads(); 4080 CU_ASSERT(g_bserrno == 0); 4081 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4082 4083 g_blob = NULL; 4084 g_bserrno = 0; 4085 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 4086 poll_threads(); 4087 CU_ASSERT(g_bserrno != 0); 4088 CU_ASSERT(g_blob == NULL); 4089 4090 g_blob = NULL; 4091 g_bserrno = -1; 4092 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 4093 poll_threads(); 4094 CU_ASSERT(g_bserrno == 0); 4095 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4096 blob_data_ro = g_blob; 4097 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 4098 CU_ASSERT(blob_data_ro->data_ro == true); 4099 CU_ASSERT(blob_data_ro->md_ro == true); 4100 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 4101 4102 g_blob = NULL; 4103 g_bserrno = -1; 4104 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 4105 poll_threads(); 4106 CU_ASSERT(g_bserrno == 0); 4107 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4108 blob_md_ro = g_blob; 4109 CU_ASSERT(blob_md_ro->data_ro == false); 4110 CU_ASSERT(blob_md_ro->md_ro == true); 4111 4112 g_bserrno = -1; 4113 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 4114 poll_threads(); 4115 CU_ASSERT(g_bserrno == 0); 4116 4117 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 4118 poll_threads(); 4119 CU_ASSERT(g_bserrno == 0); 4120 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 4121 poll_threads(); 4122 CU_ASSERT(g_bserrno == 0); 4123 4124 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4125 poll_threads(); 4126 CU_ASSERT(g_bserrno == 0); 4127 } 4128 4129 static void 4130 bs_version(void) 4131 { 4132 struct spdk_bs_super_block *super; 4133 struct spdk_bs_dev *dev; 4134 struct spdk_bs_opts opts; 4135 spdk_blob_id blobid; 4136 4137 dev = init_dev(); 4138 spdk_bs_opts_init(&opts); 4139 4140 /* Initialize a new blob store */ 4141 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 4142 poll_threads(); 4143 CU_ASSERT(g_bserrno == 0); 4144 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4145 4146 /* Unload the blob store */ 4147 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4148 poll_threads(); 4149 CU_ASSERT(g_bserrno == 0); 4150 g_bs = NULL; 4151 4152 /* 4153 * Change the bs version on disk. This will allow us to 4154 * test that the version does not get modified automatically 4155 * when loading and unloading the blobstore. 4156 */ 4157 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 4158 CU_ASSERT(super->version == SPDK_BS_VERSION); 4159 CU_ASSERT(super->clean == 1); 4160 super->version = 2; 4161 /* 4162 * Version 2 metadata does not have a used blobid mask, so clear 4163 * those fields in the super block and zero the corresponding 4164 * region on "disk". We will use this to ensure blob IDs are 4165 * correctly reconstructed. 4166 */ 4167 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 4168 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 4169 super->used_blobid_mask_start = 0; 4170 super->used_blobid_mask_len = 0; 4171 super->crc = _spdk_blob_md_page_calc_crc(super); 4172 4173 /* Load an existing blob store */ 4174 dev = init_dev(); 4175 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4176 poll_threads(); 4177 CU_ASSERT(g_bserrno == 0); 4178 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4179 CU_ASSERT(super->clean == 1); 4180 4181 /* 4182 * Create a blob - just to make sure that when we unload it 4183 * results in writing the super block (since metadata pages 4184 * were allocated. 4185 */ 4186 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 4187 poll_threads(); 4188 CU_ASSERT(g_bserrno == 0); 4189 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4190 blobid = g_blobid; 4191 4192 /* Unload the blob store */ 4193 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4194 poll_threads(); 4195 CU_ASSERT(g_bserrno == 0); 4196 g_bs = NULL; 4197 CU_ASSERT(super->version == 2); 4198 CU_ASSERT(super->used_blobid_mask_start == 0); 4199 CU_ASSERT(super->used_blobid_mask_len == 0); 4200 4201 dev = init_dev(); 4202 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4203 poll_threads(); 4204 CU_ASSERT(g_bserrno == 0); 4205 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4206 4207 g_blob = NULL; 4208 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 4209 poll_threads(); 4210 CU_ASSERT(g_bserrno == 0); 4211 CU_ASSERT(g_blob != NULL); 4212 4213 spdk_blob_close(g_blob, blob_op_complete, NULL); 4214 poll_threads(); 4215 CU_ASSERT(g_bserrno == 0); 4216 4217 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4218 poll_threads(); 4219 CU_ASSERT(g_bserrno == 0); 4220 g_bs = NULL; 4221 CU_ASSERT(super->version == 2); 4222 CU_ASSERT(super->used_blobid_mask_start == 0); 4223 CU_ASSERT(super->used_blobid_mask_len == 0); 4224 } 4225 4226 static void 4227 blob_set_xattrs(void) 4228 { 4229 struct spdk_blob_store *bs; 4230 struct spdk_bs_dev *dev; 4231 struct spdk_blob *blob; 4232 struct spdk_blob_opts opts; 4233 spdk_blob_id blobid; 4234 const void *value; 4235 size_t value_len; 4236 int rc; 4237 4238 dev = init_dev(); 4239 4240 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4241 poll_threads(); 4242 CU_ASSERT(g_bserrno == 0); 4243 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4244 bs = g_bs; 4245 4246 /* Create blob with extra attributes */ 4247 spdk_blob_opts_init(&opts); 4248 4249 opts.xattrs.names = g_xattr_names; 4250 opts.xattrs.get_value = _get_xattr_value; 4251 opts.xattrs.count = 3; 4252 opts.xattrs.ctx = &g_ctx; 4253 4254 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4255 poll_threads(); 4256 CU_ASSERT(g_bserrno == 0); 4257 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4258 blobid = g_blobid; 4259 4260 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4261 poll_threads(); 4262 CU_ASSERT(g_bserrno == 0); 4263 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4264 blob = g_blob; 4265 4266 /* Get the xattrs */ 4267 value = NULL; 4268 4269 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 4270 CU_ASSERT(rc == 0); 4271 SPDK_CU_ASSERT_FATAL(value != NULL); 4272 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 4273 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 4274 4275 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 4276 CU_ASSERT(rc == 0); 4277 SPDK_CU_ASSERT_FATAL(value != NULL); 4278 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 4279 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 4280 4281 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 4282 CU_ASSERT(rc == 0); 4283 SPDK_CU_ASSERT_FATAL(value != NULL); 4284 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 4285 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 4286 4287 /* Try to get non existing attribute */ 4288 4289 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 4290 CU_ASSERT(rc == -ENOENT); 4291 4292 spdk_blob_close(blob, blob_op_complete, NULL); 4293 poll_threads(); 4294 CU_ASSERT(g_bserrno == 0); 4295 blob = NULL; 4296 g_blob = NULL; 4297 g_blobid = SPDK_BLOBID_INVALID; 4298 4299 /* NULL callback */ 4300 spdk_blob_opts_init(&opts); 4301 opts.xattrs.names = g_xattr_names; 4302 opts.xattrs.get_value = NULL; 4303 opts.xattrs.count = 1; 4304 opts.xattrs.ctx = &g_ctx; 4305 4306 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4307 poll_threads(); 4308 CU_ASSERT(g_bserrno == -EINVAL); 4309 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4310 4311 /* NULL values */ 4312 spdk_blob_opts_init(&opts); 4313 opts.xattrs.names = g_xattr_names; 4314 opts.xattrs.get_value = _get_xattr_value_null; 4315 opts.xattrs.count = 1; 4316 opts.xattrs.ctx = NULL; 4317 4318 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4319 poll_threads(); 4320 CU_ASSERT(g_bserrno == -EINVAL); 4321 4322 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4323 poll_threads(); 4324 CU_ASSERT(g_bserrno == 0); 4325 g_bs = NULL; 4326 4327 } 4328 4329 static void 4330 blob_thin_prov_alloc(void) 4331 { 4332 struct spdk_blob_store *bs; 4333 struct spdk_bs_dev *dev; 4334 struct spdk_blob *blob; 4335 struct spdk_blob_opts opts; 4336 spdk_blob_id blobid; 4337 uint64_t free_clusters; 4338 4339 dev = init_dev(); 4340 4341 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4342 poll_threads(); 4343 CU_ASSERT(g_bserrno == 0); 4344 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4345 bs = g_bs; 4346 free_clusters = spdk_bs_free_cluster_count(bs); 4347 4348 /* Set blob as thin provisioned */ 4349 spdk_blob_opts_init(&opts); 4350 opts.thin_provision = true; 4351 4352 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4353 poll_threads(); 4354 CU_ASSERT(g_bserrno == 0); 4355 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4356 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4357 blobid = g_blobid; 4358 4359 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4360 poll_threads(); 4361 CU_ASSERT(g_bserrno == 0); 4362 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4363 blob = g_blob; 4364 4365 CU_ASSERT(blob->active.num_clusters == 0); 4366 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 4367 4368 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4369 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4370 poll_threads(); 4371 CU_ASSERT(g_bserrno == 0); 4372 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4373 CU_ASSERT(blob->active.num_clusters == 5); 4374 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4375 4376 /* Grow it to 1TB - still unallocated */ 4377 spdk_blob_resize(blob, 262144, blob_op_complete, NULL); 4378 poll_threads(); 4379 CU_ASSERT(g_bserrno == 0); 4380 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4381 CU_ASSERT(blob->active.num_clusters == 262144); 4382 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 4383 4384 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4385 poll_threads(); 4386 CU_ASSERT(g_bserrno == 0); 4387 /* Sync must not change anything */ 4388 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4389 CU_ASSERT(blob->active.num_clusters == 262144); 4390 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 4391 /* Since clusters are not allocated, 4392 * number of metadata pages is expected to be minimal. 4393 */ 4394 CU_ASSERT(blob->active.num_pages == 1); 4395 4396 /* Shrink the blob to 3 clusters - still unallocated */ 4397 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 4398 poll_threads(); 4399 CU_ASSERT(g_bserrno == 0); 4400 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4401 CU_ASSERT(blob->active.num_clusters == 3); 4402 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 4403 4404 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4405 poll_threads(); 4406 CU_ASSERT(g_bserrno == 0); 4407 /* Sync must not change anything */ 4408 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4409 CU_ASSERT(blob->active.num_clusters == 3); 4410 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 4411 4412 spdk_blob_close(blob, blob_op_complete, NULL); 4413 poll_threads(); 4414 CU_ASSERT(g_bserrno == 0); 4415 4416 /* Unload the blob store */ 4417 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4418 poll_threads(); 4419 CU_ASSERT(g_bserrno == 0); 4420 g_bs = NULL; 4421 g_blob = NULL; 4422 g_blobid = 0; 4423 4424 /* Load an existing blob store */ 4425 dev = init_dev(); 4426 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4427 poll_threads(); 4428 CU_ASSERT(g_bserrno == 0); 4429 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4430 4431 bs = g_bs; 4432 4433 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 4434 poll_threads(); 4435 CU_ASSERT(g_bserrno == 0); 4436 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4437 blob = g_blob; 4438 4439 /* Check that clusters allocation and size is still the same */ 4440 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4441 CU_ASSERT(blob->active.num_clusters == 3); 4442 4443 spdk_blob_close(blob, blob_op_complete, NULL); 4444 poll_threads(); 4445 CU_ASSERT(g_bserrno == 0); 4446 4447 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4448 poll_threads(); 4449 CU_ASSERT(g_bserrno == 0); 4450 4451 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4452 poll_threads(); 4453 CU_ASSERT(g_bserrno == 0); 4454 g_bs = NULL; 4455 } 4456 4457 static void 4458 blob_insert_cluster_msg(void) 4459 { 4460 struct spdk_blob_store *bs; 4461 struct spdk_bs_dev *dev; 4462 struct spdk_blob *blob; 4463 struct spdk_blob_opts opts; 4464 spdk_blob_id blobid; 4465 uint64_t free_clusters; 4466 4467 dev = init_dev(); 4468 4469 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4470 poll_threads(); 4471 CU_ASSERT(g_bserrno == 0); 4472 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4473 bs = g_bs; 4474 free_clusters = spdk_bs_free_cluster_count(bs); 4475 4476 /* Set blob as thin provisioned */ 4477 spdk_blob_opts_init(&opts); 4478 opts.thin_provision = true; 4479 opts.num_clusters = 4; 4480 4481 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4482 poll_threads(); 4483 CU_ASSERT(g_bserrno == 0); 4484 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4485 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4486 blobid = g_blobid; 4487 4488 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4489 poll_threads(); 4490 CU_ASSERT(g_bserrno == 0); 4491 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4492 blob = g_blob; 4493 4494 CU_ASSERT(blob->active.num_clusters == 4); 4495 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 4496 CU_ASSERT(blob->active.clusters[1] == 0); 4497 4498 _spdk_bs_claim_cluster(bs, 0xF); 4499 _spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL); 4500 poll_threads(); 4501 4502 CU_ASSERT(blob->active.clusters[1] != 0); 4503 4504 spdk_blob_close(blob, blob_op_complete, NULL); 4505 poll_threads(); 4506 CU_ASSERT(g_bserrno == 0); 4507 4508 /* Unload the blob store */ 4509 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4510 poll_threads(); 4511 CU_ASSERT(g_bserrno == 0); 4512 g_bs = NULL; 4513 g_blob = NULL; 4514 g_blobid = 0; 4515 4516 /* Load an existing blob store */ 4517 dev = init_dev(); 4518 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4519 poll_threads(); 4520 CU_ASSERT(g_bserrno == 0); 4521 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4522 4523 bs = g_bs; 4524 4525 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 4526 poll_threads(); 4527 CU_ASSERT(g_bserrno == 0); 4528 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4529 blob = g_blob; 4530 4531 CU_ASSERT(blob->active.clusters[1] != 0); 4532 4533 spdk_blob_close(blob, blob_op_complete, NULL); 4534 poll_threads(); 4535 CU_ASSERT(g_bserrno == 0); 4536 4537 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4538 poll_threads(); 4539 CU_ASSERT(g_bserrno == 0); 4540 4541 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4542 poll_threads(); 4543 CU_ASSERT(g_bserrno == 0); 4544 g_bs = NULL; 4545 } 4546 4547 static void 4548 blob_thin_prov_rw(void) 4549 { 4550 static const uint8_t zero[10 * 4096] = { 0 }; 4551 struct spdk_blob_store *bs; 4552 struct spdk_bs_dev *dev; 4553 struct spdk_blob *blob; 4554 struct spdk_io_channel *channel, *channel_thread1; 4555 struct spdk_blob_opts opts; 4556 spdk_blob_id blobid; 4557 uint64_t free_clusters; 4558 uint64_t page_size; 4559 uint8_t payload_read[10 * 4096]; 4560 uint8_t payload_write[10 * 4096]; 4561 uint64_t write_bytes; 4562 uint64_t read_bytes; 4563 4564 dev = init_dev(); 4565 4566 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4567 poll_threads(); 4568 CU_ASSERT(g_bserrno == 0); 4569 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4570 bs = g_bs; 4571 free_clusters = spdk_bs_free_cluster_count(bs); 4572 page_size = spdk_bs_get_page_size(bs); 4573 4574 channel = spdk_bs_alloc_io_channel(bs); 4575 CU_ASSERT(channel != NULL); 4576 4577 spdk_blob_opts_init(&opts); 4578 opts.thin_provision = true; 4579 4580 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4581 poll_threads(); 4582 CU_ASSERT(g_bserrno == 0); 4583 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4584 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4585 blobid = g_blobid; 4586 4587 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4588 poll_threads(); 4589 CU_ASSERT(g_bserrno == 0); 4590 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4591 blob = g_blob; 4592 4593 CU_ASSERT(blob->active.num_clusters == 0); 4594 4595 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4596 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4597 poll_threads(); 4598 CU_ASSERT(g_bserrno == 0); 4599 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4600 CU_ASSERT(blob->active.num_clusters == 5); 4601 4602 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4603 poll_threads(); 4604 CU_ASSERT(g_bserrno == 0); 4605 /* Sync must not change anything */ 4606 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4607 CU_ASSERT(blob->active.num_clusters == 5); 4608 4609 /* Payload should be all zeros from unallocated clusters */ 4610 memset(payload_read, 0xFF, sizeof(payload_read)); 4611 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4612 poll_threads(); 4613 CU_ASSERT(g_bserrno == 0); 4614 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4615 4616 write_bytes = g_dev_write_bytes; 4617 read_bytes = g_dev_read_bytes; 4618 4619 /* Perform write on thread 1. That will allocate cluster on thread 0 via send_msg */ 4620 set_thread(1); 4621 channel_thread1 = spdk_bs_alloc_io_channel(bs); 4622 CU_ASSERT(channel_thread1 != NULL); 4623 memset(payload_write, 0xE5, sizeof(payload_write)); 4624 spdk_blob_io_write(blob, channel_thread1, payload_write, 4, 10, blob_op_complete, NULL); 4625 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4626 /* Perform write on thread 0. That will try to allocate cluster, 4627 * but fail due to another thread issuing the cluster allocation first. */ 4628 set_thread(0); 4629 memset(payload_write, 0xE5, sizeof(payload_write)); 4630 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4631 CU_ASSERT(free_clusters - 2 == spdk_bs_free_cluster_count(bs)); 4632 poll_threads(); 4633 CU_ASSERT(g_bserrno == 0); 4634 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4635 /* For thin-provisioned blob we need to write 20 pages plus one page metadata and 4636 * read 0 bytes */ 4637 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 21); 4638 CU_ASSERT(g_dev_read_bytes - read_bytes == 0); 4639 4640 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4641 poll_threads(); 4642 CU_ASSERT(g_bserrno == 0); 4643 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4644 4645 spdk_blob_close(blob, blob_op_complete, NULL); 4646 poll_threads(); 4647 CU_ASSERT(g_bserrno == 0); 4648 4649 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4650 poll_threads(); 4651 CU_ASSERT(g_bserrno == 0); 4652 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4653 4654 spdk_bs_free_io_channel(channel_thread1); 4655 spdk_bs_free_io_channel(channel); 4656 poll_threads(); 4657 4658 /* Unload the blob store */ 4659 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4660 poll_threads(); 4661 CU_ASSERT(g_bserrno == 0); 4662 g_bs = NULL; 4663 g_blob = NULL; 4664 g_blobid = 0; 4665 } 4666 4667 static void 4668 blob_thin_prov_rw_iov(void) 4669 { 4670 static const uint8_t zero[10 * 4096] = { 0 }; 4671 struct spdk_blob_store *bs; 4672 struct spdk_bs_dev *dev; 4673 struct spdk_blob *blob; 4674 struct spdk_io_channel *channel; 4675 struct spdk_blob_opts opts; 4676 spdk_blob_id blobid; 4677 uint64_t free_clusters; 4678 uint8_t payload_read[10 * 4096]; 4679 uint8_t payload_write[10 * 4096]; 4680 struct iovec iov_read[3]; 4681 struct iovec iov_write[3]; 4682 4683 dev = init_dev(); 4684 4685 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4686 poll_threads(); 4687 CU_ASSERT(g_bserrno == 0); 4688 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4689 bs = g_bs; 4690 free_clusters = spdk_bs_free_cluster_count(bs); 4691 4692 channel = spdk_bs_alloc_io_channel(bs); 4693 CU_ASSERT(channel != NULL); 4694 4695 spdk_blob_opts_init(&opts); 4696 opts.thin_provision = true; 4697 4698 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4699 poll_threads(); 4700 CU_ASSERT(g_bserrno == 0); 4701 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4702 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4703 blobid = g_blobid; 4704 4705 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4706 poll_threads(); 4707 CU_ASSERT(g_bserrno == 0); 4708 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4709 blob = g_blob; 4710 4711 CU_ASSERT(blob->active.num_clusters == 0); 4712 4713 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4714 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4715 poll_threads(); 4716 CU_ASSERT(g_bserrno == 0); 4717 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4718 CU_ASSERT(blob->active.num_clusters == 5); 4719 4720 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4721 poll_threads(); 4722 CU_ASSERT(g_bserrno == 0); 4723 /* Sync must not change anything */ 4724 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4725 CU_ASSERT(blob->active.num_clusters == 5); 4726 4727 /* Payload should be all zeros from unallocated clusters */ 4728 memset(payload_read, 0xAA, sizeof(payload_read)); 4729 iov_read[0].iov_base = payload_read; 4730 iov_read[0].iov_len = 3 * 4096; 4731 iov_read[1].iov_base = payload_read + 3 * 4096; 4732 iov_read[1].iov_len = 4 * 4096; 4733 iov_read[2].iov_base = payload_read + 7 * 4096; 4734 iov_read[2].iov_len = 3 * 4096; 4735 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4736 poll_threads(); 4737 CU_ASSERT(g_bserrno == 0); 4738 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4739 4740 memset(payload_write, 0xE5, sizeof(payload_write)); 4741 iov_write[0].iov_base = payload_write; 4742 iov_write[0].iov_len = 1 * 4096; 4743 iov_write[1].iov_base = payload_write + 1 * 4096; 4744 iov_write[1].iov_len = 5 * 4096; 4745 iov_write[2].iov_base = payload_write + 6 * 4096; 4746 iov_write[2].iov_len = 4 * 4096; 4747 4748 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 4749 poll_threads(); 4750 CU_ASSERT(g_bserrno == 0); 4751 4752 memset(payload_read, 0xAA, sizeof(payload_read)); 4753 iov_read[0].iov_base = payload_read; 4754 iov_read[0].iov_len = 3 * 4096; 4755 iov_read[1].iov_base = payload_read + 3 * 4096; 4756 iov_read[1].iov_len = 4 * 4096; 4757 iov_read[2].iov_base = payload_read + 7 * 4096; 4758 iov_read[2].iov_len = 3 * 4096; 4759 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4760 poll_threads(); 4761 CU_ASSERT(g_bserrno == 0); 4762 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4763 4764 spdk_blob_close(blob, blob_op_complete, NULL); 4765 poll_threads(); 4766 CU_ASSERT(g_bserrno == 0); 4767 4768 spdk_bs_free_io_channel(channel); 4769 poll_threads(); 4770 4771 /* Unload the blob store */ 4772 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4773 poll_threads(); 4774 CU_ASSERT(g_bserrno == 0); 4775 g_bs = NULL; 4776 g_blob = NULL; 4777 g_blobid = 0; 4778 } 4779 4780 struct iter_ctx { 4781 int current_iter; 4782 spdk_blob_id blobid[4]; 4783 }; 4784 4785 static void 4786 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 4787 { 4788 struct iter_ctx *iter_ctx = arg; 4789 spdk_blob_id blobid; 4790 4791 CU_ASSERT(bserrno == 0); 4792 blobid = spdk_blob_get_id(blob); 4793 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 4794 } 4795 4796 static void 4797 bs_load_iter(void) 4798 { 4799 struct spdk_bs_dev *dev; 4800 struct iter_ctx iter_ctx = { 0 }; 4801 struct spdk_blob *blob; 4802 int i, rc; 4803 struct spdk_bs_opts opts; 4804 4805 dev = init_dev(); 4806 spdk_bs_opts_init(&opts); 4807 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4808 4809 /* Initialize a new blob store */ 4810 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 4811 poll_threads(); 4812 CU_ASSERT(g_bserrno == 0); 4813 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4814 4815 for (i = 0; i < 4; i++) { 4816 g_bserrno = -1; 4817 g_blobid = SPDK_BLOBID_INVALID; 4818 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 4819 poll_threads(); 4820 CU_ASSERT(g_bserrno == 0); 4821 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4822 iter_ctx.blobid[i] = g_blobid; 4823 4824 g_bserrno = -1; 4825 g_blob = NULL; 4826 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 4827 poll_threads(); 4828 CU_ASSERT(g_bserrno == 0); 4829 CU_ASSERT(g_blob != NULL); 4830 blob = g_blob; 4831 4832 /* Just save the blobid as an xattr for testing purposes. */ 4833 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 4834 CU_ASSERT(rc == 0); 4835 4836 /* Resize the blob */ 4837 spdk_blob_resize(blob, i, blob_op_complete, NULL); 4838 poll_threads(); 4839 CU_ASSERT(g_bserrno == 0); 4840 4841 spdk_blob_close(blob, blob_op_complete, NULL); 4842 poll_threads(); 4843 CU_ASSERT(g_bserrno == 0); 4844 } 4845 4846 g_bserrno = -1; 4847 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4848 poll_threads(); 4849 CU_ASSERT(g_bserrno == 0); 4850 4851 dev = init_dev(); 4852 spdk_bs_opts_init(&opts); 4853 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4854 opts.iter_cb_fn = test_iter; 4855 opts.iter_cb_arg = &iter_ctx; 4856 4857 /* Test blob iteration during load after a clean shutdown. */ 4858 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4859 poll_threads(); 4860 CU_ASSERT(g_bserrno == 0); 4861 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4862 4863 /* Dirty shutdown */ 4864 _spdk_bs_free(g_bs); 4865 4866 dev = init_dev(); 4867 spdk_bs_opts_init(&opts); 4868 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4869 opts.iter_cb_fn = test_iter; 4870 iter_ctx.current_iter = 0; 4871 opts.iter_cb_arg = &iter_ctx; 4872 4873 /* Test blob iteration during load after a dirty shutdown. */ 4874 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4875 poll_threads(); 4876 CU_ASSERT(g_bserrno == 0); 4877 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4878 4879 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4880 poll_threads(); 4881 CU_ASSERT(g_bserrno == 0); 4882 g_bs = NULL; 4883 } 4884 4885 static void 4886 blob_snapshot_rw(void) 4887 { 4888 static const uint8_t zero[10 * 4096] = { 0 }; 4889 struct spdk_blob_store *bs; 4890 struct spdk_bs_dev *dev; 4891 struct spdk_blob *blob, *snapshot; 4892 struct spdk_io_channel *channel; 4893 struct spdk_blob_opts opts; 4894 spdk_blob_id blobid, snapshotid; 4895 uint64_t free_clusters; 4896 uint64_t cluster_size; 4897 uint64_t page_size; 4898 uint8_t payload_read[10 * 4096]; 4899 uint8_t payload_write[10 * 4096]; 4900 uint64_t write_bytes; 4901 uint64_t read_bytes; 4902 4903 dev = init_dev(); 4904 4905 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 4906 poll_threads(); 4907 CU_ASSERT(g_bserrno == 0); 4908 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4909 bs = g_bs; 4910 free_clusters = spdk_bs_free_cluster_count(bs); 4911 cluster_size = spdk_bs_get_cluster_size(bs); 4912 page_size = spdk_bs_get_page_size(bs); 4913 4914 channel = spdk_bs_alloc_io_channel(bs); 4915 CU_ASSERT(channel != NULL); 4916 4917 spdk_blob_opts_init(&opts); 4918 opts.thin_provision = true; 4919 opts.num_clusters = 5; 4920 4921 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4922 poll_threads(); 4923 CU_ASSERT(g_bserrno == 0); 4924 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4925 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4926 blobid = g_blobid; 4927 4928 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4929 poll_threads(); 4930 CU_ASSERT(g_bserrno == 0); 4931 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4932 blob = g_blob; 4933 4934 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4935 4936 memset(payload_read, 0xFF, sizeof(payload_read)); 4937 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4938 poll_threads(); 4939 CU_ASSERT(g_bserrno == 0); 4940 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4941 4942 memset(payload_write, 0xE5, sizeof(payload_write)); 4943 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4944 poll_threads(); 4945 CU_ASSERT(g_bserrno == 0); 4946 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4947 4948 /* Create snapshot from blob */ 4949 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4950 poll_threads(); 4951 CU_ASSERT(g_bserrno == 0); 4952 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4953 snapshotid = g_blobid; 4954 4955 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4956 poll_threads(); 4957 CU_ASSERT(g_bserrno == 0); 4958 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4959 snapshot = g_blob; 4960 CU_ASSERT(snapshot->data_ro == true) 4961 CU_ASSERT(snapshot->md_ro == true) 4962 4963 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 4964 4965 write_bytes = g_dev_write_bytes; 4966 read_bytes = g_dev_read_bytes; 4967 4968 memset(payload_write, 0xAA, sizeof(payload_write)); 4969 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4970 poll_threads(); 4971 CU_ASSERT(g_bserrno == 0); 4972 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4973 4974 /* For a clone we need to allocate and copy one cluster, update one page of metadata 4975 * and then write 10 pages of payload. 4976 */ 4977 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11 + cluster_size); 4978 CU_ASSERT(g_dev_read_bytes - read_bytes == cluster_size); 4979 4980 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4981 poll_threads(); 4982 CU_ASSERT(g_bserrno == 0); 4983 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4984 4985 /* Data on snapshot should not change after write to clone */ 4986 memset(payload_write, 0xE5, sizeof(payload_write)); 4987 spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL); 4988 poll_threads(); 4989 CU_ASSERT(g_bserrno == 0); 4990 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4991 4992 spdk_blob_close(blob, blob_op_complete, NULL); 4993 poll_threads(); 4994 CU_ASSERT(g_bserrno == 0); 4995 4996 spdk_blob_close(snapshot, blob_op_complete, NULL); 4997 poll_threads(); 4998 CU_ASSERT(g_bserrno == 0); 4999 5000 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5001 poll_threads(); 5002 CU_ASSERT(g_bserrno == 0); 5003 5004 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5005 poll_threads(); 5006 CU_ASSERT(g_bserrno == 0); 5007 5008 spdk_bs_free_io_channel(channel); 5009 poll_threads(); 5010 5011 /* Unload the blob store */ 5012 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5013 poll_threads(); 5014 CU_ASSERT(g_bserrno == 0); 5015 g_bs = NULL; 5016 g_blob = NULL; 5017 g_blobid = 0; 5018 } 5019 5020 static void 5021 blob_snapshot_rw_iov(void) 5022 { 5023 static const uint8_t zero[10 * 4096] = { 0 }; 5024 struct spdk_blob_store *bs; 5025 struct spdk_bs_dev *dev; 5026 struct spdk_blob *blob, *snapshot; 5027 struct spdk_io_channel *channel; 5028 struct spdk_blob_opts opts; 5029 spdk_blob_id blobid, snapshotid; 5030 uint64_t free_clusters; 5031 uint8_t payload_read[10 * 4096]; 5032 uint8_t payload_write[10 * 4096]; 5033 struct iovec iov_read[3]; 5034 struct iovec iov_write[3]; 5035 5036 dev = init_dev(); 5037 5038 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5039 poll_threads(); 5040 CU_ASSERT(g_bserrno == 0); 5041 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5042 bs = g_bs; 5043 free_clusters = spdk_bs_free_cluster_count(bs); 5044 5045 channel = spdk_bs_alloc_io_channel(bs); 5046 CU_ASSERT(channel != NULL); 5047 5048 spdk_blob_opts_init(&opts); 5049 opts.thin_provision = true; 5050 opts.num_clusters = 5; 5051 5052 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5053 poll_threads(); 5054 CU_ASSERT(g_bserrno == 0); 5055 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5056 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5057 blobid = g_blobid; 5058 5059 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5060 poll_threads(); 5061 CU_ASSERT(g_bserrno == 0); 5062 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5063 blob = g_blob; 5064 5065 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5066 5067 /* Create snapshot from blob */ 5068 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5069 poll_threads(); 5070 CU_ASSERT(g_bserrno == 0); 5071 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5072 snapshotid = g_blobid; 5073 5074 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5075 poll_threads(); 5076 CU_ASSERT(g_bserrno == 0); 5077 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5078 snapshot = g_blob; 5079 CU_ASSERT(snapshot->data_ro == true) 5080 CU_ASSERT(snapshot->md_ro == true) 5081 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 5082 5083 /* Payload should be all zeros from unallocated clusters */ 5084 memset(payload_read, 0xAA, sizeof(payload_read)); 5085 iov_read[0].iov_base = payload_read; 5086 iov_read[0].iov_len = 3 * 4096; 5087 iov_read[1].iov_base = payload_read + 3 * 4096; 5088 iov_read[1].iov_len = 4 * 4096; 5089 iov_read[2].iov_base = payload_read + 7 * 4096; 5090 iov_read[2].iov_len = 3 * 4096; 5091 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 5092 poll_threads(); 5093 CU_ASSERT(g_bserrno == 0); 5094 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 5095 5096 memset(payload_write, 0xE5, sizeof(payload_write)); 5097 iov_write[0].iov_base = payload_write; 5098 iov_write[0].iov_len = 1 * 4096; 5099 iov_write[1].iov_base = payload_write + 1 * 4096; 5100 iov_write[1].iov_len = 5 * 4096; 5101 iov_write[2].iov_base = payload_write + 6 * 4096; 5102 iov_write[2].iov_len = 4 * 4096; 5103 5104 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 5105 poll_threads(); 5106 CU_ASSERT(g_bserrno == 0); 5107 5108 memset(payload_read, 0xAA, sizeof(payload_read)); 5109 iov_read[0].iov_base = payload_read; 5110 iov_read[0].iov_len = 3 * 4096; 5111 iov_read[1].iov_base = payload_read + 3 * 4096; 5112 iov_read[1].iov_len = 4 * 4096; 5113 iov_read[2].iov_base = payload_read + 7 * 4096; 5114 iov_read[2].iov_len = 3 * 4096; 5115 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 5116 poll_threads(); 5117 CU_ASSERT(g_bserrno == 0); 5118 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 5119 5120 spdk_blob_close(blob, blob_op_complete, NULL); 5121 poll_threads(); 5122 CU_ASSERT(g_bserrno == 0); 5123 5124 spdk_blob_close(snapshot, blob_op_complete, NULL); 5125 poll_threads(); 5126 CU_ASSERT(g_bserrno == 0); 5127 5128 spdk_bs_free_io_channel(channel); 5129 poll_threads(); 5130 5131 /* Unload the blob store */ 5132 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5133 poll_threads(); 5134 CU_ASSERT(g_bserrno == 0); 5135 g_bs = NULL; 5136 g_blob = NULL; 5137 g_blobid = 0; 5138 } 5139 5140 /** 5141 * Inflate / decouple parent rw unit tests. 5142 * 5143 * -------------- 5144 * original blob: 0 1 2 3 4 5145 * ,---------+---------+---------+---------+---------. 5146 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 5147 * +---------+---------+---------+---------+---------+ 5148 * snapshot2 | - |yyyyyyyyy| - |yyyyyyyyy| - | 5149 * +---------+---------+---------+---------+---------+ 5150 * blob | - |zzzzzzzzz| - | - | - | 5151 * '---------+---------+---------+---------+---------' 5152 * . . . . . . 5153 * -------- . . . . . . 5154 * inflate: . . . . . . 5155 * ,---------+---------+---------+---------+---------. 5156 * blob |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000| 5157 * '---------+---------+---------+---------+---------' 5158 * 5159 * NOTE: needs to allocate 4 clusters, thin provisioning removed, dependency 5160 * on snapshot2 and snapshot removed . . . 5161 * . . . . . . 5162 * ---------------- . . . . . . 5163 * decouple parent: . . . . . . 5164 * ,---------+---------+---------+---------+---------. 5165 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 5166 * +---------+---------+---------+---------+---------+ 5167 * blob | - |zzzzzzzzz| - |yyyyyyyyy| - | 5168 * '---------+---------+---------+---------+---------' 5169 * 5170 * NOTE: needs to allocate 1 cluster, 3 clusters unallocated, dependency 5171 * on snapshot2 removed and on snapshot still exists. Snapshot2 5172 * should remain a clone of snapshot. 5173 */ 5174 static void 5175 _blob_inflate_rw(bool decouple_parent) 5176 { 5177 struct spdk_blob_store *bs; 5178 struct spdk_bs_dev *dev; 5179 struct spdk_blob *blob, *snapshot, *snapshot2; 5180 struct spdk_io_channel *channel; 5181 struct spdk_blob_opts opts; 5182 spdk_blob_id blobid, snapshotid, snapshot2id; 5183 uint64_t free_clusters; 5184 uint64_t cluster_size; 5185 5186 uint64_t payload_size; 5187 uint8_t *payload_read; 5188 uint8_t *payload_write; 5189 uint8_t *payload_clone; 5190 5191 uint64_t pages_per_cluster; 5192 uint64_t pages_per_payload; 5193 5194 int i; 5195 spdk_blob_id ids[2]; 5196 size_t count; 5197 5198 dev = init_dev(); 5199 5200 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 5201 poll_threads(); 5202 CU_ASSERT(g_bserrno == 0); 5203 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5204 bs = g_bs; 5205 5206 free_clusters = spdk_bs_free_cluster_count(bs); 5207 cluster_size = spdk_bs_get_cluster_size(bs); 5208 pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs); 5209 pages_per_payload = pages_per_cluster * 5; 5210 5211 payload_size = cluster_size * 5; 5212 5213 payload_read = malloc(payload_size); 5214 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 5215 5216 payload_write = malloc(payload_size); 5217 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 5218 5219 payload_clone = malloc(payload_size); 5220 SPDK_CU_ASSERT_FATAL(payload_clone != NULL); 5221 5222 channel = spdk_bs_alloc_io_channel(bs); 5223 SPDK_CU_ASSERT_FATAL(channel != NULL); 5224 5225 /* Create blob */ 5226 spdk_blob_opts_init(&opts); 5227 opts.thin_provision = true; 5228 opts.num_clusters = 5; 5229 5230 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5231 poll_threads(); 5232 CU_ASSERT(g_bserrno == 0); 5233 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5234 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5235 blobid = g_blobid; 5236 5237 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5238 poll_threads(); 5239 CU_ASSERT(g_bserrno == 0); 5240 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5241 blob = g_blob; 5242 5243 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5244 5245 /* 1) Initial read should return zeroed payload */ 5246 memset(payload_read, 0xFF, payload_size); 5247 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5248 blob_op_complete, NULL); 5249 poll_threads(); 5250 CU_ASSERT(g_bserrno == 0); 5251 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 5252 5253 /* Fill whole blob with a pattern, except last cluster (to be sure it 5254 * isn't allocated) */ 5255 memset(payload_write, 0xE5, payload_size - cluster_size); 5256 spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload - 5257 pages_per_cluster, blob_op_complete, NULL); 5258 poll_threads(); 5259 CU_ASSERT(g_bserrno == 0); 5260 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5261 5262 /* 2) Create snapshot from blob (first level) */ 5263 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5264 poll_threads(); 5265 CU_ASSERT(g_bserrno == 0); 5266 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5267 snapshotid = g_blobid; 5268 5269 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5270 poll_threads(); 5271 CU_ASSERT(g_bserrno == 0); 5272 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5273 snapshot = g_blob; 5274 CU_ASSERT(snapshot->data_ro == true) 5275 CU_ASSERT(snapshot->md_ro == true) 5276 5277 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 5278 5279 /* Write every second cluster with a pattern. 5280 * 5281 * Last cluster shouldn't be written, to be sure that snapshot nor clone 5282 * doesn't allocate it. 5283 * 5284 * payload_clone stores expected result on "blob" read at the time and 5285 * is used only to check data consistency on clone before and after 5286 * inflation. Initially we fill it with a backing snapshots pattern 5287 * used before. 5288 */ 5289 memset(payload_clone, 0xE5, payload_size - cluster_size); 5290 memset(payload_clone + payload_size - cluster_size, 0x00, cluster_size); 5291 memset(payload_write, 0xAA, payload_size); 5292 for (i = 1; i < 5; i += 2) { 5293 spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster, 5294 pages_per_cluster, blob_op_complete, NULL); 5295 poll_threads(); 5296 CU_ASSERT(g_bserrno == 0); 5297 5298 /* Update expected result */ 5299 memcpy(payload_clone + (cluster_size * i), payload_write, 5300 cluster_size); 5301 } 5302 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5303 5304 /* Check data consistency on clone */ 5305 memset(payload_read, 0xFF, payload_size); 5306 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5307 blob_op_complete, NULL); 5308 poll_threads(); 5309 CU_ASSERT(g_bserrno == 0); 5310 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5311 5312 /* 3) Create second levels snapshot from blob */ 5313 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5314 poll_threads(); 5315 CU_ASSERT(g_bserrno == 0); 5316 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5317 snapshot2id = g_blobid; 5318 5319 spdk_bs_open_blob(bs, snapshot2id, blob_op_with_handle_complete, NULL); 5320 poll_threads(); 5321 CU_ASSERT(g_bserrno == 0); 5322 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5323 snapshot2 = g_blob; 5324 CU_ASSERT(snapshot2->data_ro == true) 5325 CU_ASSERT(snapshot2->md_ro == true) 5326 5327 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 5) 5328 5329 CU_ASSERT(snapshot2->parent_id == snapshotid); 5330 5331 /* Write one cluster on the top level blob. This cluster (1) covers 5332 * already allocated cluster in the snapshot2, so shouldn't be inflated 5333 * at all */ 5334 spdk_blob_io_write(blob, channel, payload_write, pages_per_cluster, 5335 pages_per_cluster, blob_op_complete, NULL); 5336 poll_threads(); 5337 CU_ASSERT(g_bserrno == 0); 5338 5339 /* Update expected result */ 5340 memcpy(payload_clone + cluster_size, payload_write, cluster_size); 5341 5342 /* Check data consistency on clone */ 5343 memset(payload_read, 0xFF, payload_size); 5344 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5345 blob_op_complete, NULL); 5346 poll_threads(); 5347 CU_ASSERT(g_bserrno == 0); 5348 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5349 5350 5351 /* Close all blobs */ 5352 spdk_blob_close(blob, blob_op_complete, NULL); 5353 poll_threads(); 5354 CU_ASSERT(g_bserrno == 0); 5355 5356 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5357 poll_threads(); 5358 CU_ASSERT(g_bserrno == 0); 5359 5360 spdk_blob_close(snapshot, blob_op_complete, NULL); 5361 poll_threads(); 5362 CU_ASSERT(g_bserrno == 0); 5363 5364 /* Check snapshot-clone relations */ 5365 count = 2; 5366 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5367 CU_ASSERT(count == 1); 5368 CU_ASSERT(ids[0] == snapshot2id); 5369 5370 count = 2; 5371 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5372 CU_ASSERT(count == 1); 5373 CU_ASSERT(ids[0] == blobid); 5374 5375 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshot2id); 5376 5377 free_clusters = spdk_bs_free_cluster_count(bs); 5378 if (!decouple_parent) { 5379 /* Do full blob inflation */ 5380 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 5381 poll_threads(); 5382 CU_ASSERT(g_bserrno == 0); 5383 5384 /* All clusters should be inflated (except one already allocated 5385 * in a top level blob) */ 5386 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 4); 5387 5388 /* Check if relation tree updated correctly */ 5389 count = 2; 5390 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5391 5392 /* snapshotid have one clone */ 5393 CU_ASSERT(count == 1); 5394 CU_ASSERT(ids[0] == snapshot2id); 5395 5396 /* snapshot2id have no clones */ 5397 count = 2; 5398 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5399 CU_ASSERT(count == 0); 5400 5401 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5402 } else { 5403 /* Decouple parent of blob */ 5404 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 5405 poll_threads(); 5406 CU_ASSERT(g_bserrno == 0); 5407 5408 /* Only one cluster from a parent should be inflated (second one 5409 * is covered by a cluster written on a top level blob, and 5410 * already allocated) */ 5411 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 1); 5412 5413 /* Check if relation tree updated correctly */ 5414 count = 2; 5415 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5416 5417 /* snapshotid have two clones now */ 5418 CU_ASSERT(count == 2); 5419 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5420 CU_ASSERT(ids[0] == snapshot2id || ids[1] == snapshot2id); 5421 5422 /* snapshot2id have no clones */ 5423 count = 2; 5424 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5425 CU_ASSERT(count == 0); 5426 5427 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5428 } 5429 5430 /* Try to delete snapshot2 (should pass) */ 5431 spdk_bs_delete_blob(bs, snapshot2id, blob_op_complete, NULL); 5432 poll_threads(); 5433 CU_ASSERT(g_bserrno == 0); 5434 5435 /* Try to delete base snapshot */ 5436 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5437 poll_threads(); 5438 CU_ASSERT(g_bserrno == 0); 5439 5440 /* Reopen blob after snapshot deletion */ 5441 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5442 poll_threads(); 5443 CU_ASSERT(g_bserrno == 0); 5444 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5445 blob = g_blob; 5446 5447 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5448 5449 /* Check data consistency on inflated blob */ 5450 memset(payload_read, 0xFF, payload_size); 5451 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5452 blob_op_complete, NULL); 5453 poll_threads(); 5454 CU_ASSERT(g_bserrno == 0); 5455 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5456 5457 spdk_blob_close(blob, blob_op_complete, NULL); 5458 poll_threads(); 5459 CU_ASSERT(g_bserrno == 0); 5460 5461 spdk_bs_free_io_channel(channel); 5462 poll_threads(); 5463 5464 /* Unload the blob store */ 5465 spdk_bs_unload(g_bs, bs_op_complete, NULL); 5466 poll_threads(); 5467 CU_ASSERT(g_bserrno == 0); 5468 g_bs = NULL; 5469 g_blob = NULL; 5470 g_blobid = 0; 5471 5472 free(payload_read); 5473 free(payload_write); 5474 free(payload_clone); 5475 } 5476 5477 static void 5478 blob_inflate_rw(void) 5479 { 5480 _blob_inflate_rw(false); 5481 _blob_inflate_rw(true); 5482 } 5483 5484 /** 5485 * Snapshot-clones relation test 5486 * 5487 * snapshot 5488 * | 5489 * +-----+-----+ 5490 * | | 5491 * blob(ro) snapshot2 5492 * | | 5493 * clone2 clone 5494 */ 5495 static void 5496 blob_relations(void) 5497 { 5498 struct spdk_blob_store *bs; 5499 struct spdk_bs_dev *dev; 5500 struct spdk_bs_opts bs_opts; 5501 struct spdk_blob_opts opts; 5502 struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2; 5503 spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2; 5504 int rc; 5505 size_t count; 5506 spdk_blob_id ids[10] = {}; 5507 5508 dev = init_dev(); 5509 spdk_bs_opts_init(&bs_opts); 5510 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5511 5512 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 5513 poll_threads(); 5514 CU_ASSERT(g_bserrno == 0); 5515 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5516 bs = g_bs; 5517 5518 /* 1. Create blob with 10 clusters */ 5519 5520 spdk_blob_opts_init(&opts); 5521 opts.num_clusters = 10; 5522 5523 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5524 poll_threads(); 5525 CU_ASSERT(g_bserrno == 0); 5526 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5527 blobid = g_blobid; 5528 5529 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5530 poll_threads(); 5531 CU_ASSERT(g_bserrno == 0); 5532 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5533 blob = g_blob; 5534 5535 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5536 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5537 CU_ASSERT(!spdk_blob_is_clone(blob)); 5538 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob)); 5539 5540 /* blob should not have underlying snapshot nor clones */ 5541 CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID); 5542 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5543 count = SPDK_COUNTOF(ids); 5544 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5545 CU_ASSERT(rc == 0); 5546 CU_ASSERT(count == 0); 5547 5548 5549 /* 2. Create snapshot */ 5550 5551 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5552 poll_threads(); 5553 CU_ASSERT(g_bserrno == 0); 5554 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5555 snapshotid = g_blobid; 5556 5557 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5558 poll_threads(); 5559 CU_ASSERT(g_bserrno == 0); 5560 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5561 snapshot = g_blob; 5562 5563 CU_ASSERT(spdk_blob_is_read_only(snapshot)); 5564 CU_ASSERT(spdk_blob_is_snapshot(snapshot)); 5565 CU_ASSERT(!spdk_blob_is_clone(snapshot)); 5566 CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID); 5567 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5568 5569 /* Check if original blob is converted to the clone of snapshot */ 5570 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5571 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5572 CU_ASSERT(spdk_blob_is_clone(blob)); 5573 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5574 CU_ASSERT(blob->parent_id == snapshotid); 5575 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5576 5577 count = SPDK_COUNTOF(ids); 5578 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5579 CU_ASSERT(rc == 0); 5580 CU_ASSERT(count == 1); 5581 CU_ASSERT(ids[0] == blobid); 5582 5583 5584 /* 3. Create clone from snapshot */ 5585 5586 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 5587 poll_threads(); 5588 CU_ASSERT(g_bserrno == 0); 5589 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5590 cloneid = g_blobid; 5591 5592 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 5593 poll_threads(); 5594 CU_ASSERT(g_bserrno == 0); 5595 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5596 clone = g_blob; 5597 5598 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5599 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5600 CU_ASSERT(spdk_blob_is_clone(clone)); 5601 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5602 CU_ASSERT(clone->parent_id == snapshotid); 5603 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 5604 5605 count = SPDK_COUNTOF(ids); 5606 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5607 CU_ASSERT(rc == 0); 5608 CU_ASSERT(count == 0); 5609 5610 /* Check if clone is on the snapshot's list */ 5611 count = SPDK_COUNTOF(ids); 5612 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5613 CU_ASSERT(rc == 0); 5614 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5615 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 5616 5617 5618 /* 4. Create snapshot of the clone */ 5619 5620 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 5621 poll_threads(); 5622 CU_ASSERT(g_bserrno == 0); 5623 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5624 snapshotid2 = g_blobid; 5625 5626 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 5627 poll_threads(); 5628 CU_ASSERT(g_bserrno == 0); 5629 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5630 snapshot2 = g_blob; 5631 5632 CU_ASSERT(spdk_blob_is_read_only(snapshot2)); 5633 CU_ASSERT(spdk_blob_is_snapshot(snapshot2)); 5634 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 5635 CU_ASSERT(snapshot2->parent_id == snapshotid); 5636 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5637 5638 /* Check if clone is converted to the clone of snapshot2 and snapshot2 5639 * is a child of snapshot */ 5640 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5641 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5642 CU_ASSERT(spdk_blob_is_clone(clone)); 5643 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5644 CU_ASSERT(clone->parent_id == snapshotid2); 5645 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5646 5647 count = SPDK_COUNTOF(ids); 5648 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5649 CU_ASSERT(rc == 0); 5650 CU_ASSERT(count == 1); 5651 CU_ASSERT(ids[0] == cloneid); 5652 5653 5654 /* 5. Try to create clone from read only blob */ 5655 5656 /* Mark blob as read only */ 5657 spdk_blob_set_read_only(blob); 5658 spdk_blob_sync_md(blob, blob_op_complete, NULL); 5659 poll_threads(); 5660 CU_ASSERT(g_bserrno == 0); 5661 5662 /* Check if previously created blob is read only clone */ 5663 CU_ASSERT(spdk_blob_is_read_only(blob)); 5664 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5665 CU_ASSERT(spdk_blob_is_clone(blob)); 5666 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5667 5668 /* Create clone from read only blob */ 5669 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5670 poll_threads(); 5671 CU_ASSERT(g_bserrno == 0); 5672 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5673 cloneid2 = g_blobid; 5674 5675 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 5676 poll_threads(); 5677 CU_ASSERT(g_bserrno == 0); 5678 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5679 clone2 = g_blob; 5680 5681 CU_ASSERT(!spdk_blob_is_read_only(clone2)); 5682 CU_ASSERT(!spdk_blob_is_snapshot(clone2)); 5683 CU_ASSERT(spdk_blob_is_clone(clone2)); 5684 CU_ASSERT(spdk_blob_is_thin_provisioned(clone2)); 5685 5686 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5687 5688 count = SPDK_COUNTOF(ids); 5689 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5690 CU_ASSERT(rc == 0); 5691 5692 CU_ASSERT(count == 1); 5693 CU_ASSERT(ids[0] == cloneid2); 5694 5695 /* Close blobs */ 5696 5697 spdk_blob_close(clone2, blob_op_complete, NULL); 5698 poll_threads(); 5699 CU_ASSERT(g_bserrno == 0); 5700 5701 spdk_blob_close(blob, blob_op_complete, NULL); 5702 poll_threads(); 5703 CU_ASSERT(g_bserrno == 0); 5704 5705 spdk_blob_close(clone, blob_op_complete, NULL); 5706 poll_threads(); 5707 CU_ASSERT(g_bserrno == 0); 5708 5709 spdk_blob_close(snapshot, blob_op_complete, NULL); 5710 poll_threads(); 5711 CU_ASSERT(g_bserrno == 0); 5712 5713 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5714 poll_threads(); 5715 CU_ASSERT(g_bserrno == 0); 5716 5717 /* Try to delete snapshot with more than 1 clone */ 5718 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5719 poll_threads(); 5720 CU_ASSERT(g_bserrno != 0); 5721 5722 spdk_bs_unload(bs, bs_op_complete, NULL); 5723 poll_threads(); 5724 CU_ASSERT(g_bserrno == 0); 5725 g_bs = NULL; 5726 5727 /* Load an existing blob store */ 5728 dev = init_dev(); 5729 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5730 5731 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 5732 poll_threads(); 5733 CU_ASSERT(g_bserrno == 0); 5734 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5735 bs = g_bs; 5736 5737 5738 /* NULL ids array should return number of clones in count */ 5739 count = SPDK_COUNTOF(ids); 5740 rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count); 5741 CU_ASSERT(rc == -ENOMEM); 5742 CU_ASSERT(count == 2); 5743 5744 /* incorrect array size */ 5745 count = 1; 5746 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5747 CU_ASSERT(rc == -ENOMEM); 5748 CU_ASSERT(count == 2); 5749 5750 5751 /* Verify structure of loaded blob store */ 5752 5753 /* snapshot */ 5754 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5755 5756 count = SPDK_COUNTOF(ids); 5757 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5758 CU_ASSERT(rc == 0); 5759 CU_ASSERT(count == 2); 5760 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5761 CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2); 5762 5763 /* blob */ 5764 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5765 count = SPDK_COUNTOF(ids); 5766 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5767 CU_ASSERT(rc == 0); 5768 CU_ASSERT(count == 1); 5769 CU_ASSERT(ids[0] == cloneid2); 5770 5771 /* clone */ 5772 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5773 count = SPDK_COUNTOF(ids); 5774 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5775 CU_ASSERT(rc == 0); 5776 CU_ASSERT(count == 0); 5777 5778 /* snapshot2 */ 5779 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5780 count = SPDK_COUNTOF(ids); 5781 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5782 CU_ASSERT(rc == 0); 5783 CU_ASSERT(count == 1); 5784 CU_ASSERT(ids[0] == cloneid); 5785 5786 /* clone2 */ 5787 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5788 count = SPDK_COUNTOF(ids); 5789 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 5790 CU_ASSERT(rc == 0); 5791 CU_ASSERT(count == 0); 5792 5793 /* Try to delete blob that user should not be able to remove */ 5794 5795 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5796 poll_threads(); 5797 CU_ASSERT(g_bserrno != 0); 5798 5799 /* Remove all blobs */ 5800 5801 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 5802 poll_threads(); 5803 CU_ASSERT(g_bserrno == 0); 5804 5805 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5806 poll_threads(); 5807 CU_ASSERT(g_bserrno == 0); 5808 5809 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 5810 poll_threads(); 5811 CU_ASSERT(g_bserrno == 0); 5812 5813 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5814 poll_threads(); 5815 CU_ASSERT(g_bserrno == 0); 5816 5817 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5818 poll_threads(); 5819 CU_ASSERT(g_bserrno == 0); 5820 5821 spdk_bs_unload(bs, bs_op_complete, NULL); 5822 poll_threads(); 5823 CU_ASSERT(g_bserrno == 0); 5824 5825 g_bs = NULL; 5826 } 5827 5828 /** 5829 * Snapshot-clones relation test 2 5830 * 5831 * snapshot1 5832 * | 5833 * snapshot2 5834 * | 5835 * +-----+-----+ 5836 * | | 5837 * blob(ro) snapshot3 5838 * | | 5839 * | snapshot4 5840 * | | | 5841 * clone2 clone clone3 5842 */ 5843 static void 5844 blob_relations2(void) 5845 { 5846 struct spdk_blob_store *bs; 5847 struct spdk_bs_dev *dev; 5848 struct spdk_bs_opts bs_opts; 5849 struct spdk_blob_opts opts; 5850 struct spdk_blob *blob, *snapshot1, *snapshot2, *snapshot3, *snapshot4, *clone, *clone2; 5851 spdk_blob_id blobid, snapshotid1, snapshotid2, snapshotid3, snapshotid4, cloneid, cloneid2, 5852 cloneid3; 5853 int rc; 5854 size_t count; 5855 spdk_blob_id ids[10] = {}; 5856 5857 dev = init_dev(); 5858 spdk_bs_opts_init(&bs_opts); 5859 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5860 5861 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 5862 poll_threads(); 5863 CU_ASSERT(g_bserrno == 0); 5864 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5865 bs = g_bs; 5866 5867 /* 1. Create blob with 10 clusters */ 5868 5869 spdk_blob_opts_init(&opts); 5870 opts.num_clusters = 10; 5871 5872 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 5873 poll_threads(); 5874 CU_ASSERT(g_bserrno == 0); 5875 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5876 blobid = g_blobid; 5877 5878 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5879 poll_threads(); 5880 CU_ASSERT(g_bserrno == 0); 5881 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5882 blob = g_blob; 5883 5884 /* 2. Create snapshot1 */ 5885 5886 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5887 poll_threads(); 5888 CU_ASSERT(g_bserrno == 0); 5889 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5890 snapshotid1 = g_blobid; 5891 5892 spdk_bs_open_blob(bs, snapshotid1, blob_op_with_handle_complete, NULL); 5893 poll_threads(); 5894 CU_ASSERT(g_bserrno == 0); 5895 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5896 snapshot1 = g_blob; 5897 5898 CU_ASSERT(snapshot1->parent_id == SPDK_BLOBID_INVALID); 5899 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid1) == SPDK_BLOBID_INVALID); 5900 5901 CU_ASSERT(blob->parent_id == snapshotid1); 5902 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1); 5903 5904 /* Check if blob is the clone of snapshot1 */ 5905 CU_ASSERT(blob->parent_id == snapshotid1); 5906 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1); 5907 5908 count = SPDK_COUNTOF(ids); 5909 rc = spdk_blob_get_clones(bs, snapshotid1, ids, &count); 5910 CU_ASSERT(rc == 0); 5911 CU_ASSERT(count == 1); 5912 CU_ASSERT(ids[0] == blobid); 5913 5914 /* 3. Create another snapshot */ 5915 5916 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5917 poll_threads(); 5918 CU_ASSERT(g_bserrno == 0); 5919 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5920 snapshotid2 = g_blobid; 5921 5922 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 5923 poll_threads(); 5924 CU_ASSERT(g_bserrno == 0); 5925 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5926 snapshot2 = g_blob; 5927 5928 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 5929 CU_ASSERT(snapshot2->parent_id == snapshotid1); 5930 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid1); 5931 5932 /* Check if snapshot2 is the clone of snapshot1 and blob 5933 * is a child of snapshot2 */ 5934 CU_ASSERT(blob->parent_id == snapshotid2); 5935 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2); 5936 5937 count = SPDK_COUNTOF(ids); 5938 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5939 CU_ASSERT(rc == 0); 5940 CU_ASSERT(count == 1); 5941 CU_ASSERT(ids[0] == blobid); 5942 5943 /* 4. Create clone from snapshot */ 5944 5945 spdk_bs_create_clone(bs, snapshotid2, NULL, blob_op_with_id_complete, NULL); 5946 poll_threads(); 5947 CU_ASSERT(g_bserrno == 0); 5948 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5949 cloneid = g_blobid; 5950 5951 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 5952 poll_threads(); 5953 CU_ASSERT(g_bserrno == 0); 5954 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5955 clone = g_blob; 5956 5957 CU_ASSERT(clone->parent_id == snapshotid2); 5958 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5959 5960 /* Check if clone is on the snapshot's list */ 5961 count = SPDK_COUNTOF(ids); 5962 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5963 CU_ASSERT(rc == 0); 5964 CU_ASSERT(count == 2); 5965 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5966 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 5967 5968 /* 5. Create snapshot of the clone */ 5969 5970 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 5971 poll_threads(); 5972 CU_ASSERT(g_bserrno == 0); 5973 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5974 snapshotid3 = g_blobid; 5975 5976 spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL); 5977 poll_threads(); 5978 CU_ASSERT(g_bserrno == 0); 5979 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5980 snapshot3 = g_blob; 5981 5982 CU_ASSERT(snapshot3->parent_id == snapshotid2); 5983 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2); 5984 5985 /* Check if clone is converted to the clone of snapshot3 and snapshot3 5986 * is a child of snapshot2 */ 5987 CU_ASSERT(clone->parent_id == snapshotid3); 5988 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 5989 5990 count = SPDK_COUNTOF(ids); 5991 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 5992 CU_ASSERT(rc == 0); 5993 CU_ASSERT(count == 1); 5994 CU_ASSERT(ids[0] == cloneid); 5995 5996 /* 6. Create another snapshot of the clone */ 5997 5998 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 5999 poll_threads(); 6000 CU_ASSERT(g_bserrno == 0); 6001 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6002 snapshotid4 = g_blobid; 6003 6004 spdk_bs_open_blob(bs, snapshotid4, blob_op_with_handle_complete, NULL); 6005 poll_threads(); 6006 CU_ASSERT(g_bserrno == 0); 6007 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6008 snapshot4 = g_blob; 6009 6010 CU_ASSERT(snapshot4->parent_id == snapshotid3); 6011 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid4) == snapshotid3); 6012 6013 /* Check if clone is converted to the clone of snapshot4 and snapshot4 6014 * is a child of snapshot3 */ 6015 CU_ASSERT(clone->parent_id == snapshotid4); 6016 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid4); 6017 6018 count = SPDK_COUNTOF(ids); 6019 rc = spdk_blob_get_clones(bs, snapshotid4, ids, &count); 6020 CU_ASSERT(rc == 0); 6021 CU_ASSERT(count == 1); 6022 CU_ASSERT(ids[0] == cloneid); 6023 6024 /* 7. Remove snapshot 4 */ 6025 6026 spdk_blob_close(snapshot4, blob_op_complete, NULL); 6027 poll_threads(); 6028 CU_ASSERT(g_bserrno == 0); 6029 6030 spdk_bs_delete_blob(bs, snapshotid4, blob_op_complete, NULL); 6031 poll_threads(); 6032 CU_ASSERT(g_bserrno == 0); 6033 6034 /* Check if relations are back to state from before creating snapshot 4 */ 6035 CU_ASSERT(clone->parent_id == snapshotid3); 6036 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 6037 6038 count = SPDK_COUNTOF(ids); 6039 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 6040 CU_ASSERT(rc == 0); 6041 CU_ASSERT(count == 1); 6042 CU_ASSERT(ids[0] == cloneid); 6043 6044 /* 8. Create second clone of snapshot 3 and try to remove snapshot 3 */ 6045 6046 spdk_bs_create_clone(bs, snapshotid3, NULL, blob_op_with_id_complete, NULL); 6047 poll_threads(); 6048 CU_ASSERT(g_bserrno == 0); 6049 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6050 cloneid3 = g_blobid; 6051 6052 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 6053 poll_threads(); 6054 CU_ASSERT(g_bserrno != 0); 6055 6056 /* 9. Open snapshot 3 again and try to remove it while clone 3 is closed */ 6057 6058 spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL); 6059 poll_threads(); 6060 CU_ASSERT(g_bserrno == 0); 6061 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6062 snapshot3 = g_blob; 6063 6064 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 6065 poll_threads(); 6066 CU_ASSERT(g_bserrno != 0); 6067 6068 spdk_blob_close(snapshot3, blob_op_complete, NULL); 6069 poll_threads(); 6070 CU_ASSERT(g_bserrno == 0); 6071 6072 spdk_bs_delete_blob(bs, cloneid3, blob_op_complete, NULL); 6073 poll_threads(); 6074 CU_ASSERT(g_bserrno == 0); 6075 6076 /* 10. Remove snapshot 1 */ 6077 6078 spdk_blob_close(snapshot1, blob_op_complete, NULL); 6079 poll_threads(); 6080 CU_ASSERT(g_bserrno == 0); 6081 6082 spdk_bs_delete_blob(bs, snapshotid1, blob_op_complete, NULL); 6083 poll_threads(); 6084 CU_ASSERT(g_bserrno == 0); 6085 6086 /* Check if relations are back to state from before creating snapshot 4 (before step 6) */ 6087 CU_ASSERT(snapshot2->parent_id == SPDK_BLOBID_INVALID); 6088 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID); 6089 6090 count = SPDK_COUNTOF(ids); 6091 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6092 CU_ASSERT(rc == 0); 6093 CU_ASSERT(count == 2); 6094 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 6095 CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3); 6096 6097 /* 11. Try to create clone from read only blob */ 6098 6099 /* Mark blob as read only */ 6100 spdk_blob_set_read_only(blob); 6101 spdk_blob_sync_md(blob, blob_op_complete, NULL); 6102 poll_threads(); 6103 CU_ASSERT(g_bserrno == 0); 6104 6105 /* Create clone from read only blob */ 6106 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6107 poll_threads(); 6108 CU_ASSERT(g_bserrno == 0); 6109 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6110 cloneid2 = g_blobid; 6111 6112 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 6113 poll_threads(); 6114 CU_ASSERT(g_bserrno == 0); 6115 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6116 clone2 = g_blob; 6117 6118 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 6119 6120 count = SPDK_COUNTOF(ids); 6121 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 6122 CU_ASSERT(rc == 0); 6123 CU_ASSERT(count == 1); 6124 CU_ASSERT(ids[0] == cloneid2); 6125 6126 /* Close blobs */ 6127 6128 spdk_blob_close(clone2, blob_op_complete, NULL); 6129 poll_threads(); 6130 CU_ASSERT(g_bserrno == 0); 6131 6132 spdk_blob_close(blob, blob_op_complete, NULL); 6133 poll_threads(); 6134 CU_ASSERT(g_bserrno == 0); 6135 6136 spdk_blob_close(clone, blob_op_complete, NULL); 6137 poll_threads(); 6138 CU_ASSERT(g_bserrno == 0); 6139 6140 spdk_blob_close(snapshot2, blob_op_complete, NULL); 6141 poll_threads(); 6142 CU_ASSERT(g_bserrno == 0); 6143 6144 spdk_blob_close(snapshot3, blob_op_complete, NULL); 6145 poll_threads(); 6146 CU_ASSERT(g_bserrno == 0); 6147 6148 spdk_bs_unload(bs, bs_op_complete, NULL); 6149 poll_threads(); 6150 CU_ASSERT(g_bserrno == 0); 6151 g_bs = NULL; 6152 6153 /* Load an existing blob store */ 6154 dev = init_dev(); 6155 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 6156 6157 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 6158 poll_threads(); 6159 CU_ASSERT(g_bserrno == 0); 6160 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6161 bs = g_bs; 6162 6163 /* Verify structure of loaded blob store */ 6164 6165 /* snapshot2 */ 6166 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID); 6167 6168 count = SPDK_COUNTOF(ids); 6169 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 6170 CU_ASSERT(rc == 0); 6171 CU_ASSERT(count == 2); 6172 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 6173 CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3); 6174 6175 /* blob */ 6176 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2); 6177 count = SPDK_COUNTOF(ids); 6178 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 6179 CU_ASSERT(rc == 0); 6180 CU_ASSERT(count == 1); 6181 CU_ASSERT(ids[0] == cloneid2); 6182 6183 /* clone */ 6184 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 6185 count = SPDK_COUNTOF(ids); 6186 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 6187 CU_ASSERT(rc == 0); 6188 CU_ASSERT(count == 0); 6189 6190 /* snapshot3 */ 6191 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2); 6192 count = SPDK_COUNTOF(ids); 6193 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 6194 CU_ASSERT(rc == 0); 6195 CU_ASSERT(count == 1); 6196 CU_ASSERT(ids[0] == cloneid); 6197 6198 /* clone2 */ 6199 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 6200 count = SPDK_COUNTOF(ids); 6201 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 6202 CU_ASSERT(rc == 0); 6203 CU_ASSERT(count == 0); 6204 6205 /* Try to delete all blobs in the worse possible order */ 6206 6207 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6208 poll_threads(); 6209 CU_ASSERT(g_bserrno != 0); 6210 6211 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 6212 poll_threads(); 6213 CU_ASSERT(g_bserrno == 0); 6214 6215 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6216 poll_threads(); 6217 CU_ASSERT(g_bserrno != 0); 6218 6219 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 6220 poll_threads(); 6221 CU_ASSERT(g_bserrno == 0); 6222 6223 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6224 poll_threads(); 6225 CU_ASSERT(g_bserrno == 0); 6226 6227 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 6228 poll_threads(); 6229 CU_ASSERT(g_bserrno == 0); 6230 6231 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 6232 poll_threads(); 6233 CU_ASSERT(g_bserrno == 0); 6234 6235 spdk_bs_unload(bs, bs_op_complete, NULL); 6236 poll_threads(); 6237 CU_ASSERT(g_bserrno == 0); 6238 6239 g_bs = NULL; 6240 } 6241 6242 static void 6243 test_io_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6244 { 6245 uint8_t payload_ff[64 * 512]; 6246 uint8_t payload_aa[64 * 512]; 6247 uint8_t payload_00[64 * 512]; 6248 uint8_t *cluster0, *cluster1; 6249 6250 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6251 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6252 memset(payload_00, 0x00, sizeof(payload_00)); 6253 6254 /* Try to perform I/O with io unit = 512 */ 6255 spdk_blob_io_write(blob, channel, payload_ff, 0, 1, blob_op_complete, NULL); 6256 poll_threads(); 6257 CU_ASSERT(g_bserrno == 0); 6258 6259 /* If thin provisioned is set cluster should be allocated now */ 6260 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 6261 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6262 6263 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 6264 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 6265 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6266 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6267 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 6268 6269 /* Verify write with offset on first page */ 6270 spdk_blob_io_write(blob, channel, payload_ff, 2, 1, blob_op_complete, NULL); 6271 poll_threads(); 6272 CU_ASSERT(g_bserrno == 0); 6273 6274 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6275 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6276 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6277 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6278 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6279 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 6280 6281 /* Verify write with offset on first page */ 6282 spdk_blob_io_write(blob, channel, payload_ff, 4, 4, blob_op_complete, NULL); 6283 poll_threads(); 6284 6285 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6286 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6287 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6288 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6289 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6290 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 6291 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 6292 6293 /* Verify write with offset on second page */ 6294 spdk_blob_io_write(blob, channel, payload_ff, 8, 4, blob_op_complete, NULL); 6295 poll_threads(); 6296 6297 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 6298 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6299 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6300 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6301 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6302 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 6303 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6304 6305 /* Verify write across multiple pages */ 6306 spdk_blob_io_write(blob, channel, payload_aa, 4, 8, blob_op_complete, NULL); 6307 poll_threads(); 6308 6309 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 6310 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6311 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6312 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6313 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6314 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6315 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6316 6317 /* Verify write across multiple clusters */ 6318 spdk_blob_io_write(blob, channel, payload_ff, 28, 8, blob_op_complete, NULL); 6319 poll_threads(); 6320 6321 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6322 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6323 6324 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6325 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6326 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6327 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6328 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6329 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6330 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6331 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6332 6333 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6334 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 6335 6336 /* Verify write to second cluster */ 6337 spdk_blob_io_write(blob, channel, payload_ff, 32 + 12, 2, blob_op_complete, NULL); 6338 poll_threads(); 6339 6340 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6341 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6342 6343 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6344 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 6345 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6346 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6347 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6348 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6349 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6350 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6351 6352 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6353 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 6354 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 6355 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 6356 } 6357 6358 static void 6359 test_io_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6360 { 6361 uint8_t payload_read[64 * 512]; 6362 uint8_t payload_ff[64 * 512]; 6363 uint8_t payload_aa[64 * 512]; 6364 uint8_t payload_00[64 * 512]; 6365 6366 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6367 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6368 memset(payload_00, 0x00, sizeof(payload_00)); 6369 6370 /* Read only first io unit */ 6371 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6372 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6373 * payload_read: F000 0000 | 0000 0000 ... */ 6374 memset(payload_read, 0x00, sizeof(payload_read)); 6375 spdk_blob_io_read(blob, channel, payload_read, 0, 1, blob_op_complete, NULL); 6376 poll_threads(); 6377 CU_ASSERT(g_bserrno == 0); 6378 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6379 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 6380 6381 /* Read four io_units starting from offset = 2 6382 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6383 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6384 * payload_read: F0AA 0000 | 0000 0000 ... */ 6385 6386 memset(payload_read, 0x00, sizeof(payload_read)); 6387 spdk_blob_io_read(blob, channel, payload_read, 2, 4, blob_op_complete, NULL); 6388 poll_threads(); 6389 CU_ASSERT(g_bserrno == 0); 6390 6391 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6392 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6393 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 6394 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 6395 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6396 6397 /* Read eight io_units across multiple pages 6398 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6399 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6400 * payload_read: AAAA AAAA | 0000 0000 ... */ 6401 memset(payload_read, 0x00, sizeof(payload_read)); 6402 spdk_blob_io_read(blob, channel, payload_read, 4, 8, blob_op_complete, NULL); 6403 poll_threads(); 6404 CU_ASSERT(g_bserrno == 0); 6405 6406 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 6407 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6408 6409 /* Read eight io_units across multiple clusters 6410 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 6411 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6412 * payload_read: FFFF FFFF | 0000 0000 ... */ 6413 memset(payload_read, 0x00, sizeof(payload_read)); 6414 spdk_blob_io_read(blob, channel, payload_read, 28, 8, blob_op_complete, NULL); 6415 poll_threads(); 6416 CU_ASSERT(g_bserrno == 0); 6417 6418 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 6419 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6420 6421 /* Read four io_units from second cluster 6422 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6423 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 6424 * payload_read: 00FF 0000 | 0000 0000 ... */ 6425 memset(payload_read, 0x00, sizeof(payload_read)); 6426 spdk_blob_io_read(blob, channel, payload_read, 32 + 10, 4, blob_op_complete, NULL); 6427 poll_threads(); 6428 CU_ASSERT(g_bserrno == 0); 6429 6430 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 6431 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 6432 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6433 6434 /* Read second cluster 6435 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6436 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 6437 * payload_read: FFFF 0000 | 0000 FF00 ... */ 6438 memset(payload_read, 0x00, sizeof(payload_read)); 6439 spdk_blob_io_read(blob, channel, payload_read, 32, 32, blob_op_complete, NULL); 6440 poll_threads(); 6441 CU_ASSERT(g_bserrno == 0); 6442 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 6443 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 6444 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 6445 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 6446 6447 /* Read whole two clusters 6448 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6449 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 6450 memset(payload_read, 0x00, sizeof(payload_read)); 6451 spdk_blob_io_read(blob, channel, payload_read, 0, 64, blob_op_complete, NULL); 6452 poll_threads(); 6453 CU_ASSERT(g_bserrno == 0); 6454 6455 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6456 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6457 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 6458 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 6459 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 6460 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 6461 6462 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 6463 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 6464 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 6465 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 6466 } 6467 6468 6469 static void 6470 test_io_unmap(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6471 { 6472 uint8_t payload_ff[64 * 512]; 6473 uint8_t payload_aa[64 * 512]; 6474 uint8_t payload_00[64 * 512]; 6475 uint8_t *cluster0, *cluster1; 6476 6477 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6478 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6479 memset(payload_00, 0x00, sizeof(payload_00)); 6480 6481 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6482 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6483 6484 /* Unmap */ 6485 spdk_blob_io_unmap(blob, channel, 0, 64, blob_op_complete, NULL); 6486 poll_threads(); 6487 6488 CU_ASSERT(g_bserrno == 0); 6489 6490 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 6491 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 6492 } 6493 6494 static void 6495 test_io_zeroes(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6496 { 6497 uint8_t payload_ff[64 * 512]; 6498 uint8_t payload_aa[64 * 512]; 6499 uint8_t payload_00[64 * 512]; 6500 uint8_t *cluster0, *cluster1; 6501 6502 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6503 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6504 memset(payload_00, 0x00, sizeof(payload_00)); 6505 6506 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6507 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6508 6509 /* Write zeroes */ 6510 spdk_blob_io_write_zeroes(blob, channel, 0, 64, blob_op_complete, NULL); 6511 poll_threads(); 6512 6513 CU_ASSERT(g_bserrno == 0); 6514 6515 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 6516 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 6517 } 6518 6519 6520 static void 6521 test_iov_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6522 { 6523 uint8_t payload_ff[64 * 512]; 6524 uint8_t payload_aa[64 * 512]; 6525 uint8_t payload_00[64 * 512]; 6526 uint8_t *cluster0, *cluster1; 6527 struct iovec iov[4]; 6528 6529 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6530 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6531 memset(payload_00, 0x00, sizeof(payload_00)); 6532 6533 /* Try to perform I/O with io unit = 512 */ 6534 iov[0].iov_base = payload_ff; 6535 iov[0].iov_len = 1 * 512; 6536 spdk_blob_io_writev(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 6537 poll_threads(); 6538 CU_ASSERT(g_bserrno == 0); 6539 6540 /* If thin provisioned is set cluster should be allocated now */ 6541 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 6542 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6543 6544 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 6545 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 6546 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6547 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6548 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 6549 6550 /* Verify write with offset on first page */ 6551 iov[0].iov_base = payload_ff; 6552 iov[0].iov_len = 1 * 512; 6553 spdk_blob_io_writev(blob, channel, iov, 1, 2, 1, blob_op_complete, NULL); 6554 poll_threads(); 6555 CU_ASSERT(g_bserrno == 0); 6556 6557 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6558 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6559 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6560 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6561 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6562 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 6563 6564 /* Verify write with offset on first page */ 6565 iov[0].iov_base = payload_ff; 6566 iov[0].iov_len = 4 * 512; 6567 spdk_blob_io_writev(blob, channel, iov, 1, 4, 4, blob_op_complete, NULL); 6568 poll_threads(); 6569 6570 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6571 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6572 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6573 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6574 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6575 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 6576 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 6577 6578 /* Verify write with offset on second page */ 6579 iov[0].iov_base = payload_ff; 6580 iov[0].iov_len = 4 * 512; 6581 spdk_blob_io_writev(blob, channel, iov, 1, 8, 4, blob_op_complete, NULL); 6582 poll_threads(); 6583 6584 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 6585 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6586 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6587 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6588 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6589 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 6590 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6591 6592 /* Verify write across multiple pages */ 6593 iov[0].iov_base = payload_aa; 6594 iov[0].iov_len = 8 * 512; 6595 spdk_blob_io_writev(blob, channel, iov, 1, 4, 8, blob_op_complete, NULL); 6596 poll_threads(); 6597 6598 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 6599 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6600 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6601 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6602 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6603 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6604 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6605 6606 /* Verify write across multiple clusters */ 6607 6608 iov[0].iov_base = payload_ff; 6609 iov[0].iov_len = 8 * 512; 6610 spdk_blob_io_writev(blob, channel, iov, 1, 28, 8, blob_op_complete, NULL); 6611 poll_threads(); 6612 6613 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6614 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6615 6616 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6617 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6618 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6619 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6620 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6621 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6622 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6623 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 16 * 512) == 0); 6624 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6625 6626 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6627 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 6628 6629 /* Verify write to second cluster */ 6630 6631 iov[0].iov_base = payload_ff; 6632 iov[0].iov_len = 2 * 512; 6633 spdk_blob_io_writev(blob, channel, iov, 1, 32 + 12, 2, blob_op_complete, NULL); 6634 poll_threads(); 6635 6636 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6637 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6638 6639 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6640 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 6641 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6642 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6643 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6644 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6645 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6646 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6647 6648 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6649 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 6650 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 6651 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 6652 } 6653 6654 static void 6655 test_iov_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6656 { 6657 uint8_t payload_read[64 * 512]; 6658 uint8_t payload_ff[64 * 512]; 6659 uint8_t payload_aa[64 * 512]; 6660 uint8_t payload_00[64 * 512]; 6661 struct iovec iov[4]; 6662 6663 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6664 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6665 memset(payload_00, 0x00, sizeof(payload_00)); 6666 6667 /* Read only first io unit */ 6668 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6669 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6670 * payload_read: F000 0000 | 0000 0000 ... */ 6671 memset(payload_read, 0x00, sizeof(payload_read)); 6672 iov[0].iov_base = payload_read; 6673 iov[0].iov_len = 1 * 512; 6674 spdk_blob_io_readv(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL); 6675 poll_threads(); 6676 6677 CU_ASSERT(g_bserrno == 0); 6678 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6679 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 6680 6681 /* Read four io_units starting from offset = 2 6682 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6683 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6684 * payload_read: F0AA 0000 | 0000 0000 ... */ 6685 6686 memset(payload_read, 0x00, sizeof(payload_read)); 6687 iov[0].iov_base = payload_read; 6688 iov[0].iov_len = 4 * 512; 6689 spdk_blob_io_readv(blob, channel, iov, 1, 2, 4, blob_op_complete, NULL); 6690 poll_threads(); 6691 CU_ASSERT(g_bserrno == 0); 6692 6693 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6694 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6695 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 6696 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 6697 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6698 6699 /* Read eight io_units across multiple pages 6700 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6701 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6702 * payload_read: AAAA AAAA | 0000 0000 ... */ 6703 memset(payload_read, 0x00, sizeof(payload_read)); 6704 iov[0].iov_base = payload_read; 6705 iov[0].iov_len = 4 * 512; 6706 iov[1].iov_base = payload_read + 4 * 512; 6707 iov[1].iov_len = 4 * 512; 6708 spdk_blob_io_readv(blob, channel, iov, 2, 4, 8, blob_op_complete, NULL); 6709 poll_threads(); 6710 CU_ASSERT(g_bserrno == 0); 6711 6712 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 6713 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6714 6715 /* Read eight io_units across multiple clusters 6716 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 6717 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6718 * payload_read: FFFF FFFF | 0000 0000 ... */ 6719 memset(payload_read, 0x00, sizeof(payload_read)); 6720 iov[0].iov_base = payload_read; 6721 iov[0].iov_len = 2 * 512; 6722 iov[1].iov_base = payload_read + 2 * 512; 6723 iov[1].iov_len = 2 * 512; 6724 iov[2].iov_base = payload_read + 4 * 512; 6725 iov[2].iov_len = 2 * 512; 6726 iov[3].iov_base = payload_read + 6 * 512; 6727 iov[3].iov_len = 2 * 512; 6728 spdk_blob_io_readv(blob, channel, iov, 4, 28, 8, blob_op_complete, NULL); 6729 poll_threads(); 6730 CU_ASSERT(g_bserrno == 0); 6731 6732 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 6733 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6734 6735 /* Read four io_units from second cluster 6736 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6737 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 6738 * payload_read: 00FF 0000 | 0000 0000 ... */ 6739 memset(payload_read, 0x00, sizeof(payload_read)); 6740 iov[0].iov_base = payload_read; 6741 iov[0].iov_len = 1 * 512; 6742 iov[1].iov_base = payload_read + 1 * 512; 6743 iov[1].iov_len = 3 * 512; 6744 spdk_blob_io_readv(blob, channel, iov, 2, 32 + 10, 4, blob_op_complete, NULL); 6745 poll_threads(); 6746 CU_ASSERT(g_bserrno == 0); 6747 6748 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 6749 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 6750 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6751 6752 /* Read second cluster 6753 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6754 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 6755 * payload_read: FFFF 0000 | 0000 FF00 ... */ 6756 memset(payload_read, 0x00, sizeof(payload_read)); 6757 iov[0].iov_base = payload_read; 6758 iov[0].iov_len = 1 * 512; 6759 iov[1].iov_base = payload_read + 1 * 512; 6760 iov[1].iov_len = 2 * 512; 6761 iov[2].iov_base = payload_read + 3 * 512; 6762 iov[2].iov_len = 4 * 512; 6763 iov[3].iov_base = payload_read + 7 * 512; 6764 iov[3].iov_len = 25 * 512; 6765 spdk_blob_io_readv(blob, channel, iov, 4, 32, 32, blob_op_complete, NULL); 6766 poll_threads(); 6767 CU_ASSERT(g_bserrno == 0); 6768 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 6769 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 6770 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 6771 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 6772 6773 /* Read whole two clusters 6774 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6775 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 6776 memset(payload_read, 0x00, sizeof(payload_read)); 6777 iov[0].iov_base = payload_read; 6778 iov[0].iov_len = 1 * 512; 6779 iov[1].iov_base = payload_read + 1 * 512; 6780 iov[1].iov_len = 8 * 512; 6781 iov[2].iov_base = payload_read + 9 * 512; 6782 iov[2].iov_len = 16 * 512; 6783 iov[3].iov_base = payload_read + 25 * 512; 6784 iov[3].iov_len = 39 * 512; 6785 spdk_blob_io_readv(blob, channel, iov, 4, 0, 64, blob_op_complete, NULL); 6786 poll_threads(); 6787 CU_ASSERT(g_bserrno == 0); 6788 6789 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6790 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6791 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 6792 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 6793 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 6794 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 6795 6796 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 6797 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 6798 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 6799 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 6800 } 6801 6802 static void 6803 blob_io_unit(void) 6804 { 6805 struct spdk_bs_opts bsopts; 6806 struct spdk_blob_opts opts; 6807 struct spdk_bs_dev *dev; 6808 struct spdk_blob *blob, *snapshot, *clone; 6809 spdk_blob_id blobid; 6810 struct spdk_io_channel *channel; 6811 6812 /* Create dev with 512 bytes io unit size */ 6813 6814 spdk_bs_opts_init(&bsopts); 6815 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 6816 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 6817 6818 /* Try to initialize a new blob store with unsupported io_unit */ 6819 dev = init_dev(); 6820 dev->blocklen = 512; 6821 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 6822 6823 /* Initialize a new blob store */ 6824 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 6825 poll_threads(); 6826 CU_ASSERT(g_bserrno == 0); 6827 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6828 6829 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512); 6830 channel = spdk_bs_alloc_io_channel(g_bs); 6831 6832 /* Create thick provisioned blob */ 6833 spdk_blob_opts_init(&opts); 6834 opts.thin_provision = false; 6835 opts.num_clusters = 32; 6836 6837 spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL); 6838 poll_threads(); 6839 6840 CU_ASSERT(g_bserrno == 0); 6841 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6842 blobid = g_blobid; 6843 6844 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 6845 poll_threads(); 6846 CU_ASSERT(g_bserrno == 0); 6847 CU_ASSERT(g_blob != NULL); 6848 blob = g_blob; 6849 6850 test_io_write(dev, blob, channel); 6851 test_io_read(dev, blob, channel); 6852 test_io_zeroes(dev, blob, channel); 6853 6854 test_iov_write(dev, blob, channel); 6855 test_iov_read(dev, blob, channel); 6856 6857 test_io_unmap(dev, blob, channel); 6858 6859 spdk_blob_close(blob, blob_op_complete, NULL); 6860 poll_threads(); 6861 CU_ASSERT(g_bserrno == 0); 6862 blob = NULL; 6863 g_blob = NULL; 6864 6865 /* Create thin provisioned blob */ 6866 6867 spdk_blob_opts_init(&opts); 6868 opts.thin_provision = true; 6869 opts.num_clusters = 32; 6870 6871 spdk_bs_create_blob_ext(g_bs, &opts, blob_op_with_id_complete, NULL); 6872 poll_threads(); 6873 CU_ASSERT(g_bserrno == 0); 6874 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6875 blobid = g_blobid; 6876 6877 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 6878 poll_threads(); 6879 CU_ASSERT(g_bserrno == 0); 6880 CU_ASSERT(g_blob != NULL); 6881 blob = g_blob; 6882 6883 test_io_write(dev, blob, channel); 6884 test_io_read(dev, blob, channel); 6885 6886 test_io_zeroes(dev, blob, channel); 6887 6888 test_iov_write(dev, blob, channel); 6889 test_iov_read(dev, blob, channel); 6890 6891 /* Create snapshot */ 6892 6893 spdk_bs_create_snapshot(g_bs, blobid, NULL, blob_op_with_id_complete, NULL); 6894 poll_threads(); 6895 CU_ASSERT(g_bserrno == 0); 6896 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6897 blobid = g_blobid; 6898 6899 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 6900 poll_threads(); 6901 CU_ASSERT(g_bserrno == 0); 6902 CU_ASSERT(g_blob != NULL); 6903 snapshot = g_blob; 6904 6905 spdk_bs_create_clone(g_bs, blobid, NULL, blob_op_with_id_complete, NULL); 6906 poll_threads(); 6907 CU_ASSERT(g_bserrno == 0); 6908 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6909 blobid = g_blobid; 6910 6911 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 6912 poll_threads(); 6913 CU_ASSERT(g_bserrno == 0); 6914 CU_ASSERT(g_blob != NULL); 6915 clone = g_blob; 6916 6917 test_io_read(dev, blob, channel); 6918 test_io_read(dev, snapshot, channel); 6919 test_io_read(dev, clone, channel); 6920 6921 test_iov_read(dev, blob, channel); 6922 test_iov_read(dev, snapshot, channel); 6923 test_iov_read(dev, clone, channel); 6924 6925 /* Inflate clone */ 6926 6927 spdk_bs_inflate_blob(g_bs, channel, blobid, blob_op_complete, NULL); 6928 poll_threads(); 6929 6930 CU_ASSERT(g_bserrno == 0); 6931 6932 test_io_read(dev, clone, channel); 6933 6934 test_io_unmap(dev, clone, channel); 6935 6936 test_iov_write(dev, clone, channel); 6937 test_iov_read(dev, clone, channel); 6938 6939 spdk_blob_close(blob, blob_op_complete, NULL); 6940 spdk_blob_close(snapshot, blob_op_complete, NULL); 6941 spdk_blob_close(clone, blob_op_complete, NULL); 6942 poll_threads(); 6943 CU_ASSERT(g_bserrno == 0); 6944 blob = NULL; 6945 g_blob = NULL; 6946 6947 /* Unload the blob store */ 6948 spdk_bs_unload(g_bs, bs_op_complete, NULL); 6949 poll_threads(); 6950 CU_ASSERT(g_bserrno == 0); 6951 g_bs = NULL; 6952 g_blob = NULL; 6953 g_blobid = 0; 6954 } 6955 6956 static void 6957 blob_io_unit_compatiblity(void) 6958 { 6959 struct spdk_bs_opts bsopts; 6960 struct spdk_bs_dev *dev; 6961 struct spdk_bs_super_block *super; 6962 6963 /* Create dev with 512 bytes io unit size */ 6964 6965 spdk_bs_opts_init(&bsopts); 6966 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 6967 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 6968 6969 /* Try to initialize a new blob store with unsupported io_unit */ 6970 dev = init_dev(); 6971 dev->blocklen = 512; 6972 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 6973 6974 /* Initialize a new blob store */ 6975 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 6976 poll_threads(); 6977 CU_ASSERT(g_bserrno == 0); 6978 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6979 6980 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == 512); 6981 6982 /* Unload the blob store */ 6983 spdk_bs_unload(g_bs, bs_op_complete, NULL); 6984 poll_threads(); 6985 CU_ASSERT(g_bserrno == 0); 6986 6987 /* Modify super block to behave like older version. 6988 * Check if loaded io unit size equals SPDK_BS_PAGE_SIZE */ 6989 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 6990 super->io_unit_size = 0; 6991 super->crc = _spdk_blob_md_page_calc_crc(super); 6992 6993 dev = init_dev(); 6994 dev->blocklen = 512; 6995 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 6996 6997 spdk_bs_load(dev, &bsopts, bs_op_with_handle_complete, NULL); 6998 poll_threads(); 6999 CU_ASSERT(g_bserrno == 0); 7000 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7001 7002 CU_ASSERT(spdk_bs_get_io_unit_size(g_bs) == SPDK_BS_PAGE_SIZE); 7003 7004 /* Unload the blob store */ 7005 spdk_bs_unload(g_bs, bs_op_complete, NULL); 7006 poll_threads(); 7007 CU_ASSERT(g_bserrno == 0); 7008 7009 g_bs = NULL; 7010 g_blob = NULL; 7011 g_blobid = 0; 7012 } 7013 7014 static void 7015 blob_simultaneous_operations(void) 7016 { 7017 struct spdk_blob_store *bs; 7018 struct spdk_bs_dev *dev; 7019 struct spdk_blob_opts opts; 7020 struct spdk_blob *blob, *snapshot; 7021 spdk_blob_id blobid, snapshotid; 7022 struct spdk_io_channel *channel; 7023 7024 dev = init_dev(); 7025 7026 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 7027 poll_threads(); 7028 CU_ASSERT(g_bserrno == 0); 7029 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7030 bs = g_bs; 7031 7032 channel = spdk_bs_alloc_io_channel(bs); 7033 SPDK_CU_ASSERT_FATAL(channel != NULL); 7034 7035 spdk_blob_opts_init(&opts); 7036 opts.num_clusters = 10; 7037 7038 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 7039 poll_threads(); 7040 CU_ASSERT(g_bserrno == 0); 7041 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7042 blobid = g_blobid; 7043 7044 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7045 poll_threads(); 7046 CU_ASSERT(g_bserrno == 0); 7047 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7048 blob = g_blob; 7049 7050 /* Create snapshot and try to remove blob in the same time: 7051 * - snapshot should be created successfully 7052 * - delete operation should fail w -EBUSY */ 7053 CU_ASSERT(blob->locked_operation_in_progress == false); 7054 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 7055 CU_ASSERT(blob->locked_operation_in_progress == true); 7056 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7057 CU_ASSERT(blob->locked_operation_in_progress == true); 7058 /* Deletion failure */ 7059 CU_ASSERT(g_bserrno == -EBUSY); 7060 poll_threads(); 7061 CU_ASSERT(blob->locked_operation_in_progress == false); 7062 /* Snapshot creation success */ 7063 CU_ASSERT(g_bserrno == 0); 7064 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7065 7066 snapshotid = g_blobid; 7067 7068 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 7069 poll_threads(); 7070 CU_ASSERT(g_bserrno == 0); 7071 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7072 snapshot = g_blob; 7073 7074 /* Inflate blob and try to remove blob in the same time: 7075 * - blob should be inflated successfully 7076 * - delete operation should fail w -EBUSY */ 7077 CU_ASSERT(blob->locked_operation_in_progress == false); 7078 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 7079 CU_ASSERT(blob->locked_operation_in_progress == true); 7080 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7081 CU_ASSERT(blob->locked_operation_in_progress == true); 7082 /* Deletion failure */ 7083 CU_ASSERT(g_bserrno == -EBUSY); 7084 poll_threads(); 7085 CU_ASSERT(blob->locked_operation_in_progress == false); 7086 /* Inflation success */ 7087 CU_ASSERT(g_bserrno == 0); 7088 7089 /* Clone snapshot and try to remove snapshot in the same time: 7090 * - snapshot should be cloned successfully 7091 * - delete operation should fail w -EBUSY */ 7092 CU_ASSERT(blob->locked_operation_in_progress == false); 7093 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 7094 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 7095 /* Deletion failure */ 7096 CU_ASSERT(g_bserrno == -EBUSY); 7097 poll_threads(); 7098 CU_ASSERT(blob->locked_operation_in_progress == false); 7099 /* Clone created */ 7100 CU_ASSERT(g_bserrno == 0); 7101 7102 /* Resize blob and try to remove blob in the same time: 7103 * - blob should be resized successfully 7104 * - delete operation should fail w -EBUSY */ 7105 CU_ASSERT(blob->locked_operation_in_progress == false); 7106 spdk_blob_resize(blob, 50, blob_op_complete, NULL); 7107 CU_ASSERT(blob->locked_operation_in_progress == true); 7108 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7109 CU_ASSERT(blob->locked_operation_in_progress == true); 7110 /* Deletion failure */ 7111 CU_ASSERT(g_bserrno == -EBUSY); 7112 poll_threads(); 7113 CU_ASSERT(blob->locked_operation_in_progress == false); 7114 /* Blob resized successfully */ 7115 CU_ASSERT(g_bserrno == 0); 7116 7117 spdk_blob_close(blob, blob_op_complete, NULL); 7118 poll_threads(); 7119 CU_ASSERT(g_bserrno == 0); 7120 7121 spdk_blob_close(snapshot, blob_op_complete, NULL); 7122 poll_threads(); 7123 CU_ASSERT(g_bserrno == 0); 7124 7125 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7126 poll_threads(); 7127 CU_ASSERT(g_bserrno == 0); 7128 7129 spdk_bs_unload(g_bs, bs_op_complete, NULL); 7130 poll_threads(); 7131 CU_ASSERT(g_bserrno == 0); 7132 g_bs = NULL; 7133 7134 spdk_bs_free_io_channel(channel); 7135 poll_threads(); 7136 } 7137 7138 int main(int argc, char **argv) 7139 { 7140 CU_pSuite suite = NULL; 7141 unsigned int num_failures; 7142 7143 if (CU_initialize_registry() != CUE_SUCCESS) { 7144 return CU_get_error(); 7145 } 7146 7147 suite = CU_add_suite("blob", NULL, NULL); 7148 if (suite == NULL) { 7149 CU_cleanup_registry(); 7150 return CU_get_error(); 7151 } 7152 7153 if ( 7154 CU_add_test(suite, "blob_init", blob_init) == NULL || 7155 CU_add_test(suite, "blob_open", blob_open) == NULL || 7156 CU_add_test(suite, "blob_create", blob_create) == NULL || 7157 CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL || 7158 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 7159 CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL || 7160 CU_add_test(suite, "blob_clone", blob_clone) == NULL || 7161 CU_add_test(suite, "blob_inflate", blob_inflate) == NULL || 7162 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 7163 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 7164 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 7165 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 7166 CU_add_test(suite, "blob_super", blob_super) == NULL || 7167 CU_add_test(suite, "blob_write", blob_write) == NULL || 7168 CU_add_test(suite, "blob_read", blob_read) == NULL || 7169 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 7170 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 7171 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 7172 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 7173 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 7174 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 7175 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 7176 CU_add_test(suite, "bs_load", bs_load) == NULL || 7177 CU_add_test(suite, "bs_load_pending_removal", bs_load_pending_removal) == NULL || 7178 CU_add_test(suite, "bs_load_custom_cluster_size", bs_load_custom_cluster_size) == NULL || 7179 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 7180 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 7181 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 7182 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 7183 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 7184 CU_add_test(suite, "bs_type", bs_type) == NULL || 7185 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 7186 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 7187 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 7188 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 7189 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 7190 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 7191 CU_add_test(suite, "bs_version", bs_version) == NULL || 7192 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 7193 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 7194 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 7195 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 7196 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL || 7197 CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL || 7198 CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL || 7199 CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL || 7200 CU_add_test(suite, "blob_relations", blob_relations) == NULL || 7201 CU_add_test(suite, "blob_relations2", blob_relations2) == NULL || 7202 CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL || 7203 CU_add_test(suite, "blob_snapshot_freeze_io", blob_snapshot_freeze_io) == NULL || 7204 CU_add_test(suite, "blob_operation_split_rw", blob_operation_split_rw) == NULL || 7205 CU_add_test(suite, "blob_operation_split_rw_iov", blob_operation_split_rw_iov) == NULL || 7206 CU_add_test(suite, "blob_io_unit", blob_io_unit) == NULL || 7207 CU_add_test(suite, "blob_io_unit_compatiblity", blob_io_unit_compatiblity) == NULL || 7208 CU_add_test(suite, "blob_simultaneous_operations", blob_simultaneous_operations) == NULL 7209 ) { 7210 CU_cleanup_registry(); 7211 return CU_get_error(); 7212 } 7213 7214 allocate_threads(2); 7215 set_thread(0); 7216 7217 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 7218 7219 CU_basic_set_mode(CU_BRM_VERBOSE); 7220 CU_basic_run_tests(); 7221 num_failures = CU_get_number_of_failures(); 7222 CU_cleanup_registry(); 7223 7224 free(g_dev_buffer); 7225 7226 free_threads(); 7227 7228 return num_failures; 7229 } 7230