1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2017 Intel Corporation. 3 * All rights reserved. 4 * Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5 */ 6 7 #include "spdk/stdinc.h" 8 9 #include "spdk_internal/cunit.h" 10 #include "spdk/blob.h" 11 #include "spdk/string.h" 12 13 #include "common/lib/ut_multithread.c" 14 #include "../bs_dev_common.c" 15 #include "thread/thread.c" 16 #include "blob/blobstore.c" 17 #include "blob/request.c" 18 #include "blob/zeroes.c" 19 #include "blob/blob_bs_dev.c" 20 #include "esnap_dev.c" 21 22 struct spdk_blob_store *g_bs; 23 spdk_blob_id g_blobid; 24 struct spdk_blob *g_blob, *g_blob2; 25 int g_bserrno, g_bserrno2; 26 struct spdk_xattr_names *g_names; 27 int g_done; 28 char *g_xattr_names[] = {"first", "second", "third"}; 29 char *g_xattr_values[] = {"one", "two", "three"}; 30 uint64_t g_ctx = 1729; 31 bool g_use_extent_table = false; 32 33 struct spdk_bs_super_block_ver1 { 34 uint8_t signature[8]; 35 uint32_t version; 36 uint32_t length; 37 uint32_t clean; /* If there was a clean shutdown, this is 1. */ 38 spdk_blob_id super_blob; 39 40 uint32_t cluster_size; /* In bytes */ 41 42 uint32_t used_page_mask_start; /* Offset from beginning of disk, in pages */ 43 uint32_t used_page_mask_len; /* Count, in pages */ 44 45 uint32_t used_cluster_mask_start; /* Offset from beginning of disk, in pages */ 46 uint32_t used_cluster_mask_len; /* Count, in pages */ 47 48 uint32_t md_start; /* Offset from beginning of disk, in pages */ 49 uint32_t md_len; /* Count, in pages */ 50 51 uint8_t reserved[4036]; 52 uint32_t crc; 53 } __attribute__((packed)); 54 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size"); 55 56 static struct spdk_blob *ut_blob_create_and_open(struct spdk_blob_store *bs, 57 struct spdk_blob_opts *blob_opts); 58 static void ut_blob_close_and_delete(struct spdk_blob_store *bs, struct spdk_blob *blob); 59 static void suite_blob_setup(void); 60 static void suite_blob_cleanup(void); 61 62 DEFINE_STUB(spdk_memory_domain_memzero, int, (struct spdk_memory_domain *src_domain, 63 void *src_domain_ctx, struct iovec *iov, uint32_t iovcnt, void (*cpl_cb)(void *, int), 64 void *cpl_cb_arg), 0); 65 66 static bool 67 is_esnap_clone(struct spdk_blob *_blob, const void *id, size_t id_len) 68 { 69 const void *val = NULL; 70 size_t len = 0; 71 bool c0, c1, c2, c3; 72 73 CU_ASSERT(blob_get_xattr_value(_blob, BLOB_EXTERNAL_SNAPSHOT_ID, &val, &len, 74 true) == 0); 75 CU_ASSERT((c0 = (len == id_len))); 76 CU_ASSERT((c1 = (val != NULL && memcmp(val, id, len) == 0))); 77 CU_ASSERT((c2 = !!(_blob->invalid_flags & SPDK_BLOB_EXTERNAL_SNAPSHOT))); 78 CU_ASSERT((c3 = (_blob->parent_id == SPDK_BLOBID_EXTERNAL_SNAPSHOT))); 79 80 return c0 && c1 && c2 && c3; 81 } 82 83 static bool 84 is_not_esnap_clone(struct spdk_blob *_blob) 85 { 86 const void *val = NULL; 87 size_t len = 0; 88 bool c1, c2, c3, c4; 89 90 CU_ASSERT((c1 = (blob_get_xattr_value(_blob, BLOB_EXTERNAL_SNAPSHOT_ID, &val, &len, 91 true) == -ENOENT))); 92 CU_ASSERT((c2 = (val == NULL))); 93 CU_ASSERT((c3 = ((_blob->invalid_flags & SPDK_BLOB_EXTERNAL_SNAPSHOT) == 0))); 94 CU_ASSERT((c4 = (_blob->parent_id != SPDK_BLOBID_EXTERNAL_SNAPSHOT))); 95 96 return c1 && c2 && c3 && c4; 97 } 98 99 #define UT_ASSERT_IS_ESNAP_CLONE(_blob, _id, _len) CU_ASSERT(is_esnap_clone(_blob, _id, _len)) 100 #define UT_ASSERT_IS_NOT_ESNAP_CLONE(_blob) CU_ASSERT(is_not_esnap_clone(_blob)) 101 102 static void 103 _get_xattr_value(void *arg, const char *name, 104 const void **value, size_t *value_len) 105 { 106 uint64_t i; 107 108 SPDK_CU_ASSERT_FATAL(value_len != NULL); 109 SPDK_CU_ASSERT_FATAL(value != NULL); 110 CU_ASSERT(arg == &g_ctx); 111 112 for (i = 0; i < sizeof(g_xattr_names); i++) { 113 if (!strcmp(name, g_xattr_names[i])) { 114 *value_len = strlen(g_xattr_values[i]); 115 *value = g_xattr_values[i]; 116 break; 117 } 118 } 119 } 120 121 static void 122 _get_xattr_value_null(void *arg, const char *name, 123 const void **value, size_t *value_len) 124 { 125 SPDK_CU_ASSERT_FATAL(value_len != NULL); 126 SPDK_CU_ASSERT_FATAL(value != NULL); 127 CU_ASSERT(arg == NULL); 128 129 *value_len = 0; 130 *value = NULL; 131 } 132 133 static int 134 _get_snapshots_count(struct spdk_blob_store *bs) 135 { 136 struct spdk_blob_list *snapshot = NULL; 137 int count = 0; 138 139 TAILQ_FOREACH(snapshot, &bs->snapshots, link) { 140 count += 1; 141 } 142 143 return count; 144 } 145 146 static void 147 ut_spdk_blob_opts_init(struct spdk_blob_opts *opts) 148 { 149 spdk_blob_opts_init(opts, sizeof(*opts)); 150 opts->use_extent_table = g_use_extent_table; 151 } 152 153 static void 154 bs_op_complete(void *cb_arg, int bserrno) 155 { 156 g_bserrno = bserrno; 157 } 158 159 static void 160 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 161 int bserrno) 162 { 163 g_bs = bs; 164 g_bserrno = bserrno; 165 } 166 167 static void 168 blob_op_complete(void *cb_arg, int bserrno) 169 { 170 if (cb_arg != NULL) { 171 int *errp = cb_arg; 172 173 *errp = bserrno; 174 } 175 g_bserrno = bserrno; 176 } 177 178 static void 179 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 180 { 181 g_blobid = blobid; 182 g_bserrno = bserrno; 183 } 184 185 static void 186 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 187 { 188 g_blob = blb; 189 g_bserrno = bserrno; 190 } 191 192 static void 193 blob_op_with_handle_complete2(void *cb_arg, struct spdk_blob *blob, int bserrno) 194 { 195 if (g_blob == NULL) { 196 g_blob = blob; 197 g_bserrno = bserrno; 198 } else { 199 g_blob2 = blob; 200 g_bserrno2 = bserrno; 201 } 202 } 203 204 static void 205 ut_bs_reload(struct spdk_blob_store **bs, struct spdk_bs_opts *opts) 206 { 207 struct spdk_bs_dev *dev; 208 209 /* Unload the blob store */ 210 spdk_bs_unload(*bs, bs_op_complete, NULL); 211 poll_threads(); 212 CU_ASSERT(g_bserrno == 0); 213 214 dev = init_dev(); 215 /* Load an existing blob store */ 216 spdk_bs_load(dev, opts, bs_op_with_handle_complete, NULL); 217 poll_threads(); 218 CU_ASSERT(g_bserrno == 0); 219 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 220 *bs = g_bs; 221 222 g_bserrno = -1; 223 } 224 225 static void 226 ut_bs_dirty_load(struct spdk_blob_store **bs, struct spdk_bs_opts *opts) 227 { 228 struct spdk_bs_dev *dev; 229 230 /* Dirty shutdown */ 231 bs_free(*bs); 232 233 dev = init_dev(); 234 /* Load an existing blob store */ 235 spdk_bs_load(dev, opts, bs_op_with_handle_complete, NULL); 236 poll_threads(); 237 CU_ASSERT(g_bserrno == 0); 238 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 239 *bs = g_bs; 240 241 g_bserrno = -1; 242 } 243 244 static void 245 blob_init(void) 246 { 247 struct spdk_blob_store *bs; 248 struct spdk_bs_dev *dev; 249 250 dev = init_dev(); 251 252 /* should fail for an unsupported blocklen */ 253 dev->blocklen = 500; 254 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 255 poll_threads(); 256 CU_ASSERT(g_bserrno == -EINVAL); 257 258 dev = init_dev(); 259 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 260 poll_threads(); 261 CU_ASSERT(g_bserrno == 0); 262 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 263 bs = g_bs; 264 265 spdk_bs_unload(bs, bs_op_complete, NULL); 266 poll_threads(); 267 CU_ASSERT(g_bserrno == 0); 268 g_bs = NULL; 269 } 270 271 static void 272 blob_super(void) 273 { 274 struct spdk_blob_store *bs = g_bs; 275 spdk_blob_id blobid; 276 struct spdk_blob_opts blob_opts; 277 278 /* Get the super blob without having set one */ 279 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 280 poll_threads(); 281 CU_ASSERT(g_bserrno == -ENOENT); 282 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 283 284 /* Create a blob */ 285 ut_spdk_blob_opts_init(&blob_opts); 286 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 287 poll_threads(); 288 CU_ASSERT(g_bserrno == 0); 289 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 290 blobid = g_blobid; 291 292 /* Set the blob as the super blob */ 293 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 294 poll_threads(); 295 CU_ASSERT(g_bserrno == 0); 296 297 /* Get the super blob */ 298 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 299 poll_threads(); 300 CU_ASSERT(g_bserrno == 0); 301 CU_ASSERT(blobid == g_blobid); 302 } 303 304 static void 305 blob_open(void) 306 { 307 struct spdk_blob_store *bs = g_bs; 308 struct spdk_blob *blob; 309 struct spdk_blob_opts blob_opts; 310 spdk_blob_id blobid, blobid2; 311 312 ut_spdk_blob_opts_init(&blob_opts); 313 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 314 poll_threads(); 315 CU_ASSERT(g_bserrno == 0); 316 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 317 blobid = g_blobid; 318 319 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 320 poll_threads(); 321 CU_ASSERT(g_bserrno == 0); 322 CU_ASSERT(g_blob != NULL); 323 blob = g_blob; 324 325 blobid2 = spdk_blob_get_id(blob); 326 CU_ASSERT(blobid == blobid2); 327 328 /* Try to open file again. It should return success. */ 329 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 330 poll_threads(); 331 CU_ASSERT(g_bserrno == 0); 332 CU_ASSERT(blob == g_blob); 333 334 spdk_blob_close(blob, blob_op_complete, NULL); 335 poll_threads(); 336 CU_ASSERT(g_bserrno == 0); 337 338 /* 339 * Close the file a second time, releasing the second reference. This 340 * should succeed. 341 */ 342 blob = g_blob; 343 spdk_blob_close(blob, blob_op_complete, NULL); 344 poll_threads(); 345 CU_ASSERT(g_bserrno == 0); 346 347 /* 348 * Try to open file again. It should succeed. This tests the case 349 * where the file is opened, closed, then re-opened again. 350 */ 351 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 352 poll_threads(); 353 CU_ASSERT(g_bserrno == 0); 354 CU_ASSERT(g_blob != NULL); 355 blob = g_blob; 356 spdk_blob_close(blob, blob_op_complete, NULL); 357 poll_threads(); 358 CU_ASSERT(g_bserrno == 0); 359 360 /* Try to open file twice in succession. This should return the same 361 * blob object. 362 */ 363 g_blob = NULL; 364 g_blob2 = NULL; 365 g_bserrno = -1; 366 g_bserrno2 = -1; 367 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete2, NULL); 368 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete2, NULL); 369 poll_threads(); 370 CU_ASSERT(g_bserrno == 0); 371 CU_ASSERT(g_bserrno2 == 0); 372 CU_ASSERT(g_blob != NULL); 373 CU_ASSERT(g_blob2 != NULL); 374 CU_ASSERT(g_blob == g_blob2); 375 376 g_bserrno = -1; 377 spdk_blob_close(g_blob, blob_op_complete, NULL); 378 poll_threads(); 379 CU_ASSERT(g_bserrno == 0); 380 381 ut_blob_close_and_delete(bs, g_blob); 382 } 383 384 static void 385 blob_create(void) 386 { 387 struct spdk_blob_store *bs = g_bs; 388 struct spdk_blob *blob; 389 struct spdk_blob_opts opts; 390 spdk_blob_id blobid; 391 392 /* Create blob with 10 clusters */ 393 394 ut_spdk_blob_opts_init(&opts); 395 opts.num_clusters = 10; 396 397 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 398 poll_threads(); 399 CU_ASSERT(g_bserrno == 0); 400 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 401 blobid = g_blobid; 402 403 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 404 poll_threads(); 405 CU_ASSERT(g_bserrno == 0); 406 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 407 blob = g_blob; 408 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 409 410 spdk_blob_close(blob, blob_op_complete, NULL); 411 poll_threads(); 412 CU_ASSERT(g_bserrno == 0); 413 414 /* Create blob with 0 clusters */ 415 416 ut_spdk_blob_opts_init(&opts); 417 opts.num_clusters = 0; 418 419 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 420 poll_threads(); 421 CU_ASSERT(g_bserrno == 0); 422 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 423 blobid = g_blobid; 424 425 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 426 poll_threads(); 427 CU_ASSERT(g_bserrno == 0); 428 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 429 blob = g_blob; 430 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 431 432 spdk_blob_close(blob, blob_op_complete, NULL); 433 poll_threads(); 434 CU_ASSERT(g_bserrno == 0); 435 436 /* Create blob with default options (opts == NULL) */ 437 438 spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL); 439 poll_threads(); 440 CU_ASSERT(g_bserrno == 0); 441 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 442 blobid = g_blobid; 443 444 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 445 poll_threads(); 446 CU_ASSERT(g_bserrno == 0); 447 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 448 blob = g_blob; 449 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 450 451 spdk_blob_close(blob, blob_op_complete, NULL); 452 poll_threads(); 453 CU_ASSERT(g_bserrno == 0); 454 455 /* Try to create blob with size larger than blobstore */ 456 457 ut_spdk_blob_opts_init(&opts); 458 opts.num_clusters = bs->total_clusters + 1; 459 460 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 461 poll_threads(); 462 CU_ASSERT(g_bserrno == -ENOSPC); 463 } 464 465 static void 466 blob_create_zero_extent(void) 467 { 468 struct spdk_blob_store *bs = g_bs; 469 struct spdk_blob *blob; 470 spdk_blob_id blobid; 471 472 /* Create blob with default options (opts == NULL) */ 473 spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL); 474 poll_threads(); 475 CU_ASSERT(g_bserrno == 0); 476 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 477 blobid = g_blobid; 478 479 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 480 poll_threads(); 481 CU_ASSERT(g_bserrno == 0); 482 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 483 blob = g_blob; 484 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 485 CU_ASSERT(blob->extent_table_found == true); 486 CU_ASSERT(blob->active.extent_pages_array_size == 0); 487 CU_ASSERT(blob->active.extent_pages == NULL); 488 489 spdk_blob_close(blob, blob_op_complete, NULL); 490 poll_threads(); 491 CU_ASSERT(g_bserrno == 0); 492 493 /* Create blob with NULL internal options */ 494 bs_create_blob(bs, NULL, NULL, blob_op_with_id_complete, NULL); 495 poll_threads(); 496 CU_ASSERT(g_bserrno == 0); 497 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 498 blobid = g_blobid; 499 500 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 501 poll_threads(); 502 CU_ASSERT(g_bserrno == 0); 503 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 504 blob = g_blob; 505 CU_ASSERT(TAILQ_FIRST(&blob->xattrs_internal) == NULL); 506 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 507 CU_ASSERT(blob->extent_table_found == true); 508 CU_ASSERT(blob->active.extent_pages_array_size == 0); 509 CU_ASSERT(blob->active.extent_pages == NULL); 510 511 spdk_blob_close(blob, blob_op_complete, NULL); 512 poll_threads(); 513 CU_ASSERT(g_bserrno == 0); 514 } 515 516 /* 517 * Create and delete one blob in a loop over and over again. This helps ensure 518 * that the internal bit masks tracking used clusters and md_pages are being 519 * tracked correctly. 520 */ 521 static void 522 blob_create_loop(void) 523 { 524 struct spdk_blob_store *bs = g_bs; 525 struct spdk_blob_opts opts; 526 uint32_t i, loop_count; 527 528 loop_count = 4 * spdk_max(spdk_bit_array_capacity(bs->used_md_pages), 529 spdk_bit_pool_capacity(bs->used_clusters)); 530 531 for (i = 0; i < loop_count; i++) { 532 ut_spdk_blob_opts_init(&opts); 533 opts.num_clusters = 1; 534 g_bserrno = -1; 535 g_blobid = SPDK_BLOBID_INVALID; 536 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 537 poll_threads(); 538 CU_ASSERT(g_bserrno == 0); 539 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 540 spdk_bs_delete_blob(bs, g_blobid, blob_op_complete, NULL); 541 poll_threads(); 542 CU_ASSERT(g_bserrno == 0); 543 } 544 } 545 546 static void 547 blob_create_fail(void) 548 { 549 struct spdk_blob_store *bs = g_bs; 550 struct spdk_blob_opts opts; 551 spdk_blob_id blobid; 552 uint32_t used_blobids_count = spdk_bit_array_count_set(bs->used_blobids); 553 uint32_t used_md_pages_count = spdk_bit_array_count_set(bs->used_md_pages); 554 555 /* NULL callback */ 556 ut_spdk_blob_opts_init(&opts); 557 opts.xattrs.names = g_xattr_names; 558 opts.xattrs.get_value = NULL; 559 opts.xattrs.count = 1; 560 opts.xattrs.ctx = &g_ctx; 561 562 blobid = spdk_bit_array_find_first_clear(bs->used_md_pages, 0); 563 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 564 poll_threads(); 565 CU_ASSERT(g_bserrno == -EINVAL); 566 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 567 CU_ASSERT(spdk_bit_array_count_set(bs->used_blobids) == used_blobids_count); 568 CU_ASSERT(spdk_bit_array_count_set(bs->used_md_pages) == used_md_pages_count); 569 570 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 571 poll_threads(); 572 CU_ASSERT(g_bserrno == -ENOENT); 573 SPDK_CU_ASSERT_FATAL(g_blob == NULL); 574 575 ut_bs_reload(&bs, NULL); 576 CU_ASSERT(spdk_bit_array_count_set(bs->used_blobids) == used_blobids_count); 577 CU_ASSERT(spdk_bit_array_count_set(bs->used_md_pages) == used_md_pages_count); 578 579 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 580 poll_threads(); 581 CU_ASSERT(g_blob == NULL); 582 CU_ASSERT(g_bserrno == -ENOENT); 583 } 584 585 static void 586 blob_create_internal(void) 587 { 588 struct spdk_blob_store *bs = g_bs; 589 struct spdk_blob *blob; 590 struct spdk_blob_opts opts; 591 struct spdk_blob_xattr_opts internal_xattrs; 592 const void *value; 593 size_t value_len; 594 spdk_blob_id blobid; 595 int rc; 596 597 /* Create blob with custom xattrs */ 598 599 ut_spdk_blob_opts_init(&opts); 600 blob_xattrs_init(&internal_xattrs); 601 internal_xattrs.count = 3; 602 internal_xattrs.names = g_xattr_names; 603 internal_xattrs.get_value = _get_xattr_value; 604 internal_xattrs.ctx = &g_ctx; 605 606 bs_create_blob(bs, &opts, &internal_xattrs, blob_op_with_id_complete, NULL); 607 poll_threads(); 608 CU_ASSERT(g_bserrno == 0); 609 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 610 blobid = g_blobid; 611 612 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 613 poll_threads(); 614 CU_ASSERT(g_bserrno == 0); 615 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 616 blob = g_blob; 617 618 rc = blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len, true); 619 CU_ASSERT(rc == 0); 620 SPDK_CU_ASSERT_FATAL(value != NULL); 621 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 622 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 623 624 rc = blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len, true); 625 CU_ASSERT(rc == 0); 626 SPDK_CU_ASSERT_FATAL(value != NULL); 627 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 628 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 629 630 rc = blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len, true); 631 CU_ASSERT(rc == 0); 632 SPDK_CU_ASSERT_FATAL(value != NULL); 633 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 634 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 635 636 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 637 CU_ASSERT(rc != 0); 638 639 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 640 CU_ASSERT(rc != 0); 641 642 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 643 CU_ASSERT(rc != 0); 644 645 spdk_blob_close(blob, blob_op_complete, NULL); 646 poll_threads(); 647 CU_ASSERT(g_bserrno == 0); 648 649 /* Create blob with NULL internal options */ 650 651 bs_create_blob(bs, NULL, NULL, blob_op_with_id_complete, NULL); 652 poll_threads(); 653 CU_ASSERT(g_bserrno == 0); 654 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 655 blobid = g_blobid; 656 657 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 658 poll_threads(); 659 CU_ASSERT(g_bserrno == 0); 660 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 661 CU_ASSERT(TAILQ_FIRST(&g_blob->xattrs_internal) == NULL); 662 CU_ASSERT(spdk_blob_get_num_clusters(g_blob) == 0); 663 664 blob = g_blob; 665 666 spdk_blob_close(blob, blob_op_complete, NULL); 667 poll_threads(); 668 CU_ASSERT(g_bserrno == 0); 669 } 670 671 static void 672 blob_thin_provision(void) 673 { 674 struct spdk_blob_store *bs; 675 struct spdk_bs_dev *dev; 676 struct spdk_blob *blob; 677 struct spdk_blob_opts opts; 678 struct spdk_bs_opts bs_opts; 679 spdk_blob_id blobid; 680 681 dev = init_dev(); 682 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 683 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 684 685 /* Initialize a new blob store */ 686 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 687 poll_threads(); 688 CU_ASSERT(g_bserrno == 0); 689 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 690 691 bs = g_bs; 692 693 /* Create blob with thin provisioning enabled */ 694 695 ut_spdk_blob_opts_init(&opts); 696 opts.thin_provision = true; 697 opts.num_clusters = 10; 698 699 blob = ut_blob_create_and_open(bs, &opts); 700 blobid = spdk_blob_get_id(blob); 701 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 702 /* In thin provisioning with num_clusters is set, if not using the 703 * extent table, there is no allocation. If extent table is used, 704 * there is related allocation happened. */ 705 if (blob->extent_table_found == true) { 706 CU_ASSERT(blob->active.extent_pages_array_size > 0); 707 CU_ASSERT(blob->active.extent_pages != NULL); 708 } else { 709 CU_ASSERT(blob->active.extent_pages_array_size == 0); 710 CU_ASSERT(blob->active.extent_pages == NULL); 711 } 712 713 spdk_blob_close(blob, blob_op_complete, NULL); 714 CU_ASSERT(g_bserrno == 0); 715 716 /* Do not shut down cleanly. This makes sure that when we load again 717 * and try to recover a valid used_cluster map, that blobstore will 718 * ignore clusters with index 0 since these are unallocated clusters. 719 */ 720 ut_bs_dirty_load(&bs, &bs_opts); 721 722 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 723 poll_threads(); 724 CU_ASSERT(g_bserrno == 0); 725 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 726 blob = g_blob; 727 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 728 729 ut_blob_close_and_delete(bs, blob); 730 731 spdk_bs_unload(bs, bs_op_complete, NULL); 732 poll_threads(); 733 CU_ASSERT(g_bserrno == 0); 734 g_bs = NULL; 735 } 736 737 static void 738 blob_snapshot(void) 739 { 740 struct spdk_blob_store *bs = g_bs; 741 struct spdk_blob *blob; 742 struct spdk_blob *snapshot, *snapshot2; 743 struct spdk_blob_bs_dev *blob_bs_dev; 744 struct spdk_blob_opts opts; 745 struct spdk_blob_xattr_opts xattrs; 746 spdk_blob_id blobid; 747 spdk_blob_id snapshotid; 748 spdk_blob_id snapshotid2; 749 const void *value; 750 size_t value_len; 751 int rc; 752 spdk_blob_id ids[2]; 753 size_t count; 754 755 /* Create blob with 10 clusters */ 756 ut_spdk_blob_opts_init(&opts); 757 opts.num_clusters = 10; 758 759 blob = ut_blob_create_and_open(bs, &opts); 760 blobid = spdk_blob_get_id(blob); 761 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 762 763 /* Create snapshot from blob */ 764 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 0); 765 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 766 poll_threads(); 767 CU_ASSERT(g_bserrno == 0); 768 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 769 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1); 770 snapshotid = g_blobid; 771 772 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 773 poll_threads(); 774 CU_ASSERT(g_bserrno == 0); 775 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 776 snapshot = g_blob; 777 CU_ASSERT(snapshot->data_ro == true); 778 CU_ASSERT(snapshot->md_ro == true); 779 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 780 781 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 782 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 783 CU_ASSERT(spdk_mem_all_zero(blob->active.clusters, 784 blob->active.num_clusters * sizeof(blob->active.clusters[0]))); 785 786 /* Try to create snapshot from clone with xattrs */ 787 xattrs.names = g_xattr_names; 788 xattrs.get_value = _get_xattr_value; 789 xattrs.count = 3; 790 xattrs.ctx = &g_ctx; 791 spdk_bs_create_snapshot(bs, blobid, &xattrs, blob_op_with_id_complete, NULL); 792 poll_threads(); 793 CU_ASSERT(g_bserrno == 0); 794 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 795 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2); 796 snapshotid2 = g_blobid; 797 798 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 799 CU_ASSERT(g_bserrno == 0); 800 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 801 snapshot2 = g_blob; 802 CU_ASSERT(snapshot2->data_ro == true); 803 CU_ASSERT(snapshot2->md_ro == true); 804 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 10); 805 806 /* Confirm that blob is backed by snapshot2 and snapshot2 is backed by snapshot */ 807 CU_ASSERT(snapshot->back_bs_dev == NULL); 808 SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL); 809 SPDK_CU_ASSERT_FATAL(snapshot2->back_bs_dev != NULL); 810 811 blob_bs_dev = (struct spdk_blob_bs_dev *)blob->back_bs_dev; 812 CU_ASSERT(blob_bs_dev->blob == snapshot2); 813 814 blob_bs_dev = (struct spdk_blob_bs_dev *)snapshot2->back_bs_dev; 815 CU_ASSERT(blob_bs_dev->blob == snapshot); 816 817 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[0], &value, &value_len); 818 CU_ASSERT(rc == 0); 819 SPDK_CU_ASSERT_FATAL(value != NULL); 820 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 821 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 822 823 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[1], &value, &value_len); 824 CU_ASSERT(rc == 0); 825 SPDK_CU_ASSERT_FATAL(value != NULL); 826 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 827 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 828 829 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[2], &value, &value_len); 830 CU_ASSERT(rc == 0); 831 SPDK_CU_ASSERT_FATAL(value != NULL); 832 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 833 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 834 835 /* Confirm that blob is clone of snapshot2, and snapshot2 is clone of snapshot */ 836 count = 2; 837 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid2, ids, &count) == 0); 838 CU_ASSERT(count == 1); 839 CU_ASSERT(ids[0] == blobid); 840 841 count = 2; 842 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 843 CU_ASSERT(count == 1); 844 CU_ASSERT(ids[0] == snapshotid2); 845 846 /* Try to create snapshot from snapshot */ 847 spdk_bs_create_snapshot(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 848 poll_threads(); 849 CU_ASSERT(g_bserrno == -EINVAL); 850 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 851 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2); 852 853 /* Delete blob and confirm that it is no longer on snapshot2 clone list */ 854 ut_blob_close_and_delete(bs, blob); 855 count = 2; 856 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid2, ids, &count) == 0); 857 CU_ASSERT(count == 0); 858 859 /* Delete snapshot2 and confirm that it is no longer on snapshot clone list */ 860 ut_blob_close_and_delete(bs, snapshot2); 861 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1); 862 count = 2; 863 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid2, ids, &count) == 0); 864 CU_ASSERT(count == 0); 865 866 ut_blob_close_and_delete(bs, snapshot); 867 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 0); 868 } 869 870 static void 871 blob_snapshot_freeze_io(void) 872 { 873 struct spdk_io_channel *channel; 874 struct spdk_bs_channel *bs_channel; 875 struct spdk_blob_store *bs = g_bs; 876 struct spdk_blob *blob; 877 struct spdk_blob_opts opts; 878 spdk_blob_id blobid; 879 uint32_t num_of_pages = 10; 880 uint8_t payload_read[num_of_pages * SPDK_BS_PAGE_SIZE]; 881 uint8_t payload_write[num_of_pages * SPDK_BS_PAGE_SIZE]; 882 uint8_t payload_zero[num_of_pages * SPDK_BS_PAGE_SIZE]; 883 884 memset(payload_write, 0xE5, sizeof(payload_write)); 885 memset(payload_read, 0x00, sizeof(payload_read)); 886 memset(payload_zero, 0x00, sizeof(payload_zero)); 887 888 /* Test freeze I/O during snapshot */ 889 channel = spdk_bs_alloc_io_channel(bs); 890 bs_channel = spdk_io_channel_get_ctx(channel); 891 892 /* Create blob with 10 clusters */ 893 ut_spdk_blob_opts_init(&opts); 894 opts.num_clusters = 10; 895 opts.thin_provision = false; 896 897 blob = ut_blob_create_and_open(bs, &opts); 898 blobid = spdk_blob_get_id(blob); 899 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 900 901 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 902 903 /* This is implementation specific. 904 * Flag 'frozen_io' is set in _spdk_bs_snapshot_freeze_cpl callback. 905 * Four async I/O operations happen before that. */ 906 poll_thread_times(0, 5); 907 908 CU_ASSERT(TAILQ_EMPTY(&bs_channel->queued_io)); 909 910 /* Blob I/O should be frozen here */ 911 CU_ASSERT(blob->frozen_refcnt == 1); 912 913 /* Write to the blob */ 914 spdk_blob_io_write(blob, channel, payload_write, 0, num_of_pages, blob_op_complete, NULL); 915 916 /* Verify that I/O is queued */ 917 CU_ASSERT(!TAILQ_EMPTY(&bs_channel->queued_io)); 918 /* Verify that payload is not written to disk, at this point the blobs already switched */ 919 CU_ASSERT(blob->active.clusters[0] == 0); 920 921 /* Finish all operations including spdk_bs_create_snapshot */ 922 poll_threads(); 923 924 /* Verify snapshot */ 925 CU_ASSERT(g_bserrno == 0); 926 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 927 928 /* Verify that blob has unset frozen_io */ 929 CU_ASSERT(blob->frozen_refcnt == 0); 930 931 /* Verify that postponed I/O completed successfully by comparing payload */ 932 spdk_blob_io_read(blob, channel, payload_read, 0, num_of_pages, blob_op_complete, NULL); 933 poll_threads(); 934 CU_ASSERT(g_bserrno == 0); 935 CU_ASSERT(memcmp(payload_write, payload_read, num_of_pages * SPDK_BS_PAGE_SIZE) == 0); 936 937 spdk_bs_free_io_channel(channel); 938 poll_threads(); 939 940 ut_blob_close_and_delete(bs, blob); 941 } 942 943 static void 944 blob_clone(void) 945 { 946 struct spdk_blob_store *bs = g_bs; 947 struct spdk_blob_opts opts; 948 struct spdk_blob *blob, *snapshot, *clone; 949 spdk_blob_id blobid, cloneid, snapshotid; 950 struct spdk_blob_xattr_opts xattrs; 951 const void *value; 952 size_t value_len; 953 int rc; 954 955 /* Create blob with 10 clusters */ 956 957 ut_spdk_blob_opts_init(&opts); 958 opts.num_clusters = 10; 959 960 blob = ut_blob_create_and_open(bs, &opts); 961 blobid = spdk_blob_get_id(blob); 962 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 963 964 /* Create snapshot */ 965 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 966 poll_threads(); 967 CU_ASSERT(g_bserrno == 0); 968 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 969 snapshotid = g_blobid; 970 971 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 972 poll_threads(); 973 CU_ASSERT(g_bserrno == 0); 974 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 975 snapshot = g_blob; 976 CU_ASSERT(snapshot->data_ro == true); 977 CU_ASSERT(snapshot->md_ro == true); 978 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 979 980 spdk_blob_close(snapshot, blob_op_complete, NULL); 981 poll_threads(); 982 CU_ASSERT(g_bserrno == 0); 983 984 /* Create clone from snapshot with xattrs */ 985 xattrs.names = g_xattr_names; 986 xattrs.get_value = _get_xattr_value; 987 xattrs.count = 3; 988 xattrs.ctx = &g_ctx; 989 990 spdk_bs_create_clone(bs, snapshotid, &xattrs, blob_op_with_id_complete, NULL); 991 poll_threads(); 992 CU_ASSERT(g_bserrno == 0); 993 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 994 cloneid = g_blobid; 995 996 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 997 poll_threads(); 998 CU_ASSERT(g_bserrno == 0); 999 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1000 clone = g_blob; 1001 CU_ASSERT(clone->data_ro == false); 1002 CU_ASSERT(clone->md_ro == false); 1003 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 1004 1005 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[0], &value, &value_len); 1006 CU_ASSERT(rc == 0); 1007 SPDK_CU_ASSERT_FATAL(value != NULL); 1008 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 1009 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 1010 1011 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[1], &value, &value_len); 1012 CU_ASSERT(rc == 0); 1013 SPDK_CU_ASSERT_FATAL(value != NULL); 1014 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 1015 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 1016 1017 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[2], &value, &value_len); 1018 CU_ASSERT(rc == 0); 1019 SPDK_CU_ASSERT_FATAL(value != NULL); 1020 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 1021 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 1022 1023 1024 spdk_blob_close(clone, blob_op_complete, NULL); 1025 poll_threads(); 1026 CU_ASSERT(g_bserrno == 0); 1027 1028 /* Try to create clone from not read only blob */ 1029 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 1030 poll_threads(); 1031 CU_ASSERT(g_bserrno == -EINVAL); 1032 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 1033 1034 /* Mark blob as read only */ 1035 spdk_blob_set_read_only(blob); 1036 spdk_blob_sync_md(blob, blob_op_complete, NULL); 1037 poll_threads(); 1038 CU_ASSERT(g_bserrno == 0); 1039 1040 /* Create clone from read only blob */ 1041 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 1042 poll_threads(); 1043 CU_ASSERT(g_bserrno == 0); 1044 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1045 cloneid = g_blobid; 1046 1047 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 1048 poll_threads(); 1049 CU_ASSERT(g_bserrno == 0); 1050 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1051 clone = g_blob; 1052 CU_ASSERT(clone->data_ro == false); 1053 CU_ASSERT(clone->md_ro == false); 1054 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 1055 1056 ut_blob_close_and_delete(bs, clone); 1057 ut_blob_close_and_delete(bs, blob); 1058 } 1059 1060 static void 1061 _blob_inflate(bool decouple_parent) 1062 { 1063 struct spdk_blob_store *bs = g_bs; 1064 struct spdk_blob_opts opts; 1065 struct spdk_blob *blob, *snapshot; 1066 spdk_blob_id blobid, snapshotid; 1067 struct spdk_io_channel *channel; 1068 uint64_t free_clusters; 1069 1070 channel = spdk_bs_alloc_io_channel(bs); 1071 SPDK_CU_ASSERT_FATAL(channel != NULL); 1072 1073 /* Create blob with 10 clusters */ 1074 1075 ut_spdk_blob_opts_init(&opts); 1076 opts.num_clusters = 10; 1077 opts.thin_provision = true; 1078 1079 blob = ut_blob_create_and_open(bs, &opts); 1080 blobid = spdk_blob_get_id(blob); 1081 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1082 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true); 1083 1084 /* 1) Blob with no parent */ 1085 if (decouple_parent) { 1086 /* Decouple parent of blob with no parent (should fail) */ 1087 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 1088 poll_threads(); 1089 CU_ASSERT(g_bserrno != 0); 1090 } else { 1091 /* Inflate of thin blob with no parent should made it thick */ 1092 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 1093 poll_threads(); 1094 CU_ASSERT(g_bserrno == 0); 1095 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false); 1096 } 1097 1098 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 1099 poll_threads(); 1100 CU_ASSERT(g_bserrno == 0); 1101 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1102 snapshotid = g_blobid; 1103 1104 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true); 1105 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1106 1107 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 1108 poll_threads(); 1109 CU_ASSERT(g_bserrno == 0); 1110 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1111 snapshot = g_blob; 1112 CU_ASSERT(snapshot->data_ro == true); 1113 CU_ASSERT(snapshot->md_ro == true); 1114 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 1115 1116 spdk_blob_close(snapshot, blob_op_complete, NULL); 1117 poll_threads(); 1118 CU_ASSERT(g_bserrno == 0); 1119 1120 free_clusters = spdk_bs_free_cluster_count(bs); 1121 1122 /* 2) Blob with parent */ 1123 if (!decouple_parent) { 1124 /* Do full blob inflation */ 1125 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 1126 poll_threads(); 1127 CU_ASSERT(g_bserrno == 0); 1128 /* all 10 clusters should be allocated */ 1129 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 10); 1130 } else { 1131 /* Decouple parent of blob */ 1132 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 1133 poll_threads(); 1134 CU_ASSERT(g_bserrno == 0); 1135 /* when only parent is removed, none of the clusters should be allocated */ 1136 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters); 1137 } 1138 1139 /* Now, it should be possible to delete snapshot */ 1140 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 1141 poll_threads(); 1142 CU_ASSERT(g_bserrno == 0); 1143 1144 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1145 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == decouple_parent); 1146 1147 spdk_bs_free_io_channel(channel); 1148 poll_threads(); 1149 1150 ut_blob_close_and_delete(bs, blob); 1151 } 1152 1153 static void 1154 blob_inflate(void) 1155 { 1156 _blob_inflate(false); 1157 _blob_inflate(true); 1158 } 1159 1160 static void 1161 blob_delete(void) 1162 { 1163 struct spdk_blob_store *bs = g_bs; 1164 struct spdk_blob_opts blob_opts; 1165 spdk_blob_id blobid; 1166 1167 /* Create a blob and then delete it. */ 1168 ut_spdk_blob_opts_init(&blob_opts); 1169 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 1170 poll_threads(); 1171 CU_ASSERT(g_bserrno == 0); 1172 CU_ASSERT(g_blobid > 0); 1173 blobid = g_blobid; 1174 1175 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 1176 poll_threads(); 1177 CU_ASSERT(g_bserrno == 0); 1178 1179 /* Try to open the blob */ 1180 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1181 poll_threads(); 1182 CU_ASSERT(g_bserrno == -ENOENT); 1183 } 1184 1185 static void 1186 blob_resize_test(void) 1187 { 1188 struct spdk_blob_store *bs = g_bs; 1189 struct spdk_blob *blob; 1190 uint64_t free_clusters; 1191 1192 free_clusters = spdk_bs_free_cluster_count(bs); 1193 1194 blob = ut_blob_create_and_open(bs, NULL); 1195 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 1196 1197 /* Confirm that resize fails if blob is marked read-only. */ 1198 blob->md_ro = true; 1199 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1200 poll_threads(); 1201 CU_ASSERT(g_bserrno == -EPERM); 1202 blob->md_ro = false; 1203 1204 /* The blob started at 0 clusters. Resize it to be 5. */ 1205 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1206 poll_threads(); 1207 CU_ASSERT(g_bserrno == 0); 1208 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 1209 1210 /* Shrink the blob to 3 clusters. This will not actually release 1211 * the old clusters until the blob is synced. 1212 */ 1213 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 1214 poll_threads(); 1215 CU_ASSERT(g_bserrno == 0); 1216 /* Verify there are still 5 clusters in use */ 1217 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 1218 1219 spdk_blob_sync_md(blob, blob_op_complete, NULL); 1220 poll_threads(); 1221 CU_ASSERT(g_bserrno == 0); 1222 /* Now there are only 3 clusters in use */ 1223 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 1224 1225 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 1226 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 1227 poll_threads(); 1228 CU_ASSERT(g_bserrno == 0); 1229 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 1230 1231 /* Try to resize the blob to size larger than blobstore. */ 1232 spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL); 1233 poll_threads(); 1234 CU_ASSERT(g_bserrno == -ENOSPC); 1235 1236 ut_blob_close_and_delete(bs, blob); 1237 } 1238 1239 static void 1240 blob_read_only(void) 1241 { 1242 struct spdk_blob_store *bs; 1243 struct spdk_bs_dev *dev; 1244 struct spdk_blob *blob; 1245 struct spdk_bs_opts opts; 1246 spdk_blob_id blobid; 1247 int rc; 1248 1249 dev = init_dev(); 1250 spdk_bs_opts_init(&opts, sizeof(opts)); 1251 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1252 1253 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1254 poll_threads(); 1255 CU_ASSERT(g_bserrno == 0); 1256 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1257 bs = g_bs; 1258 1259 blob = ut_blob_create_and_open(bs, NULL); 1260 blobid = spdk_blob_get_id(blob); 1261 1262 rc = spdk_blob_set_read_only(blob); 1263 CU_ASSERT(rc == 0); 1264 1265 CU_ASSERT(blob->data_ro == false); 1266 CU_ASSERT(blob->md_ro == false); 1267 1268 spdk_blob_sync_md(blob, bs_op_complete, NULL); 1269 poll_threads(); 1270 1271 CU_ASSERT(blob->data_ro == true); 1272 CU_ASSERT(blob->md_ro == true); 1273 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1274 1275 spdk_blob_close(blob, blob_op_complete, NULL); 1276 poll_threads(); 1277 CU_ASSERT(g_bserrno == 0); 1278 1279 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1280 poll_threads(); 1281 CU_ASSERT(g_bserrno == 0); 1282 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1283 blob = g_blob; 1284 1285 CU_ASSERT(blob->data_ro == true); 1286 CU_ASSERT(blob->md_ro == true); 1287 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1288 1289 spdk_blob_close(blob, blob_op_complete, NULL); 1290 poll_threads(); 1291 CU_ASSERT(g_bserrno == 0); 1292 1293 ut_bs_reload(&bs, &opts); 1294 1295 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1296 poll_threads(); 1297 CU_ASSERT(g_bserrno == 0); 1298 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1299 blob = g_blob; 1300 1301 CU_ASSERT(blob->data_ro == true); 1302 CU_ASSERT(blob->md_ro == true); 1303 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1304 1305 ut_blob_close_and_delete(bs, blob); 1306 1307 spdk_bs_unload(bs, bs_op_complete, NULL); 1308 poll_threads(); 1309 CU_ASSERT(g_bserrno == 0); 1310 } 1311 1312 static void 1313 channel_ops(void) 1314 { 1315 struct spdk_blob_store *bs = g_bs; 1316 struct spdk_io_channel *channel; 1317 1318 channel = spdk_bs_alloc_io_channel(bs); 1319 CU_ASSERT(channel != NULL); 1320 1321 spdk_bs_free_io_channel(channel); 1322 poll_threads(); 1323 } 1324 1325 static void 1326 blob_write(void) 1327 { 1328 struct spdk_blob_store *bs = g_bs; 1329 struct spdk_blob *blob = g_blob; 1330 struct spdk_io_channel *channel; 1331 uint64_t pages_per_cluster; 1332 uint8_t payload[10 * 4096]; 1333 1334 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1335 1336 channel = spdk_bs_alloc_io_channel(bs); 1337 CU_ASSERT(channel != NULL); 1338 1339 /* Write to a blob with 0 size */ 1340 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1341 poll_threads(); 1342 CU_ASSERT(g_bserrno == -EINVAL); 1343 1344 /* Resize the blob */ 1345 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1346 poll_threads(); 1347 CU_ASSERT(g_bserrno == 0); 1348 1349 /* Confirm that write fails if blob is marked read-only. */ 1350 blob->data_ro = true; 1351 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1352 poll_threads(); 1353 CU_ASSERT(g_bserrno == -EPERM); 1354 blob->data_ro = false; 1355 1356 /* Write to the blob */ 1357 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1358 poll_threads(); 1359 CU_ASSERT(g_bserrno == 0); 1360 1361 /* Write starting beyond the end */ 1362 spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1363 NULL); 1364 poll_threads(); 1365 CU_ASSERT(g_bserrno == -EINVAL); 1366 1367 /* Write starting at a valid location but going off the end */ 1368 spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1369 blob_op_complete, NULL); 1370 poll_threads(); 1371 CU_ASSERT(g_bserrno == -EINVAL); 1372 1373 spdk_bs_free_io_channel(channel); 1374 poll_threads(); 1375 } 1376 1377 static void 1378 blob_read(void) 1379 { 1380 struct spdk_blob_store *bs = g_bs; 1381 struct spdk_blob *blob = g_blob; 1382 struct spdk_io_channel *channel; 1383 uint64_t pages_per_cluster; 1384 uint8_t payload[10 * 4096]; 1385 1386 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1387 1388 channel = spdk_bs_alloc_io_channel(bs); 1389 CU_ASSERT(channel != NULL); 1390 1391 /* Read from a blob with 0 size */ 1392 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1393 poll_threads(); 1394 CU_ASSERT(g_bserrno == -EINVAL); 1395 1396 /* Resize the blob */ 1397 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1398 poll_threads(); 1399 CU_ASSERT(g_bserrno == 0); 1400 1401 /* Confirm that read passes if blob is marked read-only. */ 1402 blob->data_ro = true; 1403 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1404 poll_threads(); 1405 CU_ASSERT(g_bserrno == 0); 1406 blob->data_ro = false; 1407 1408 /* Read from the blob */ 1409 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1410 poll_threads(); 1411 CU_ASSERT(g_bserrno == 0); 1412 1413 /* Read starting beyond the end */ 1414 spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1415 NULL); 1416 poll_threads(); 1417 CU_ASSERT(g_bserrno == -EINVAL); 1418 1419 /* Read starting at a valid location but going off the end */ 1420 spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1421 blob_op_complete, NULL); 1422 poll_threads(); 1423 CU_ASSERT(g_bserrno == -EINVAL); 1424 1425 spdk_bs_free_io_channel(channel); 1426 poll_threads(); 1427 } 1428 1429 static void 1430 blob_rw_verify(void) 1431 { 1432 struct spdk_blob_store *bs = g_bs; 1433 struct spdk_blob *blob = g_blob; 1434 struct spdk_io_channel *channel; 1435 uint8_t payload_read[10 * 4096]; 1436 uint8_t payload_write[10 * 4096]; 1437 1438 channel = spdk_bs_alloc_io_channel(bs); 1439 CU_ASSERT(channel != NULL); 1440 1441 spdk_blob_resize(blob, 32, blob_op_complete, NULL); 1442 poll_threads(); 1443 CU_ASSERT(g_bserrno == 0); 1444 1445 memset(payload_write, 0xE5, sizeof(payload_write)); 1446 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 1447 poll_threads(); 1448 CU_ASSERT(g_bserrno == 0); 1449 1450 memset(payload_read, 0x00, sizeof(payload_read)); 1451 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 1452 poll_threads(); 1453 CU_ASSERT(g_bserrno == 0); 1454 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 1455 1456 spdk_bs_free_io_channel(channel); 1457 poll_threads(); 1458 } 1459 1460 static void 1461 blob_rw_verify_iov(void) 1462 { 1463 struct spdk_blob_store *bs = g_bs; 1464 struct spdk_blob *blob; 1465 struct spdk_io_channel *channel; 1466 uint8_t payload_read[10 * 4096]; 1467 uint8_t payload_write[10 * 4096]; 1468 struct iovec iov_read[3]; 1469 struct iovec iov_write[3]; 1470 void *buf; 1471 1472 channel = spdk_bs_alloc_io_channel(bs); 1473 CU_ASSERT(channel != NULL); 1474 1475 blob = ut_blob_create_and_open(bs, NULL); 1476 1477 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1478 poll_threads(); 1479 CU_ASSERT(g_bserrno == 0); 1480 1481 /* 1482 * Manually adjust the offset of the blob's second cluster. This allows 1483 * us to make sure that the readv/write code correctly accounts for I/O 1484 * that cross cluster boundaries. Start by asserting that the allocated 1485 * clusters are where we expect before modifying the second cluster. 1486 */ 1487 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 1488 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 1489 blob->active.clusters[1] = 3 * 256; 1490 1491 memset(payload_write, 0xE5, sizeof(payload_write)); 1492 iov_write[0].iov_base = payload_write; 1493 iov_write[0].iov_len = 1 * 4096; 1494 iov_write[1].iov_base = payload_write + 1 * 4096; 1495 iov_write[1].iov_len = 5 * 4096; 1496 iov_write[2].iov_base = payload_write + 6 * 4096; 1497 iov_write[2].iov_len = 4 * 4096; 1498 /* 1499 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1500 * will get written to the first cluster, the last 4 to the second cluster. 1501 */ 1502 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1503 poll_threads(); 1504 CU_ASSERT(g_bserrno == 0); 1505 1506 memset(payload_read, 0xAA, sizeof(payload_read)); 1507 iov_read[0].iov_base = payload_read; 1508 iov_read[0].iov_len = 3 * 4096; 1509 iov_read[1].iov_base = payload_read + 3 * 4096; 1510 iov_read[1].iov_len = 4 * 4096; 1511 iov_read[2].iov_base = payload_read + 7 * 4096; 1512 iov_read[2].iov_len = 3 * 4096; 1513 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 1514 poll_threads(); 1515 CU_ASSERT(g_bserrno == 0); 1516 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 1517 1518 buf = calloc(1, 256 * 4096); 1519 SPDK_CU_ASSERT_FATAL(buf != NULL); 1520 /* Check that cluster 2 on "disk" was not modified. */ 1521 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 1522 free(buf); 1523 1524 spdk_blob_close(blob, blob_op_complete, NULL); 1525 poll_threads(); 1526 CU_ASSERT(g_bserrno == 0); 1527 1528 spdk_bs_free_io_channel(channel); 1529 poll_threads(); 1530 } 1531 1532 static uint32_t 1533 bs_channel_get_req_count(struct spdk_io_channel *_channel) 1534 { 1535 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 1536 struct spdk_bs_request_set *set; 1537 uint32_t count = 0; 1538 1539 TAILQ_FOREACH(set, &channel->reqs, link) { 1540 count++; 1541 } 1542 1543 return count; 1544 } 1545 1546 static void 1547 blob_rw_verify_iov_nomem(void) 1548 { 1549 struct spdk_blob_store *bs = g_bs; 1550 struct spdk_blob *blob = g_blob; 1551 struct spdk_io_channel *channel; 1552 uint8_t payload_write[10 * 4096]; 1553 struct iovec iov_write[3]; 1554 uint32_t req_count; 1555 1556 channel = spdk_bs_alloc_io_channel(bs); 1557 CU_ASSERT(channel != NULL); 1558 1559 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1560 poll_threads(); 1561 CU_ASSERT(g_bserrno == 0); 1562 1563 /* 1564 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1565 * will get written to the first cluster, the last 4 to the second cluster. 1566 */ 1567 iov_write[0].iov_base = payload_write; 1568 iov_write[0].iov_len = 1 * 4096; 1569 iov_write[1].iov_base = payload_write + 1 * 4096; 1570 iov_write[1].iov_len = 5 * 4096; 1571 iov_write[2].iov_base = payload_write + 6 * 4096; 1572 iov_write[2].iov_len = 4 * 4096; 1573 MOCK_SET(calloc, NULL); 1574 req_count = bs_channel_get_req_count(channel); 1575 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1576 poll_threads(); 1577 CU_ASSERT(g_bserrno = -ENOMEM); 1578 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 1579 MOCK_CLEAR(calloc); 1580 1581 spdk_bs_free_io_channel(channel); 1582 poll_threads(); 1583 } 1584 1585 static void 1586 blob_rw_iov_read_only(void) 1587 { 1588 struct spdk_blob_store *bs = g_bs; 1589 struct spdk_blob *blob = g_blob; 1590 struct spdk_io_channel *channel; 1591 uint8_t payload_read[4096]; 1592 uint8_t payload_write[4096]; 1593 struct iovec iov_read; 1594 struct iovec iov_write; 1595 1596 channel = spdk_bs_alloc_io_channel(bs); 1597 CU_ASSERT(channel != NULL); 1598 1599 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1600 poll_threads(); 1601 CU_ASSERT(g_bserrno == 0); 1602 1603 /* Verify that writev failed if read_only flag is set. */ 1604 blob->data_ro = true; 1605 iov_write.iov_base = payload_write; 1606 iov_write.iov_len = sizeof(payload_write); 1607 spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL); 1608 poll_threads(); 1609 CU_ASSERT(g_bserrno == -EPERM); 1610 1611 /* Verify that reads pass if data_ro flag is set. */ 1612 iov_read.iov_base = payload_read; 1613 iov_read.iov_len = sizeof(payload_read); 1614 spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL); 1615 poll_threads(); 1616 CU_ASSERT(g_bserrno == 0); 1617 1618 spdk_bs_free_io_channel(channel); 1619 poll_threads(); 1620 } 1621 1622 static void 1623 _blob_io_read_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel, 1624 uint8_t *payload, uint64_t offset, uint64_t length, 1625 spdk_blob_op_complete cb_fn, void *cb_arg) 1626 { 1627 uint64_t i; 1628 uint8_t *buf; 1629 uint64_t page_size = spdk_bs_get_page_size(blob->bs); 1630 1631 /* To be sure that operation is NOT split, read one page at the time */ 1632 buf = payload; 1633 for (i = 0; i < length; i++) { 1634 spdk_blob_io_read(blob, channel, buf, i + offset, 1, blob_op_complete, NULL); 1635 poll_threads(); 1636 if (g_bserrno != 0) { 1637 /* Pass the error code up */ 1638 break; 1639 } 1640 buf += page_size; 1641 } 1642 1643 cb_fn(cb_arg, g_bserrno); 1644 } 1645 1646 static void 1647 _blob_io_write_no_split(struct spdk_blob *blob, struct spdk_io_channel *channel, 1648 uint8_t *payload, uint64_t offset, uint64_t length, 1649 spdk_blob_op_complete cb_fn, void *cb_arg) 1650 { 1651 uint64_t i; 1652 uint8_t *buf; 1653 uint64_t page_size = spdk_bs_get_page_size(blob->bs); 1654 1655 /* To be sure that operation is NOT split, write one page at the time */ 1656 buf = payload; 1657 for (i = 0; i < length; i++) { 1658 spdk_blob_io_write(blob, channel, buf, i + offset, 1, blob_op_complete, NULL); 1659 poll_threads(); 1660 if (g_bserrno != 0) { 1661 /* Pass the error code up */ 1662 break; 1663 } 1664 buf += page_size; 1665 } 1666 1667 cb_fn(cb_arg, g_bserrno); 1668 } 1669 1670 static void 1671 blob_operation_split_rw(void) 1672 { 1673 struct spdk_blob_store *bs = g_bs; 1674 struct spdk_blob *blob; 1675 struct spdk_io_channel *channel; 1676 struct spdk_blob_opts opts; 1677 uint64_t cluster_size; 1678 1679 uint64_t payload_size; 1680 uint8_t *payload_read; 1681 uint8_t *payload_write; 1682 uint8_t *payload_pattern; 1683 1684 uint64_t page_size; 1685 uint64_t pages_per_cluster; 1686 uint64_t pages_per_payload; 1687 1688 uint64_t i; 1689 1690 cluster_size = spdk_bs_get_cluster_size(bs); 1691 page_size = spdk_bs_get_page_size(bs); 1692 pages_per_cluster = cluster_size / page_size; 1693 pages_per_payload = pages_per_cluster * 5; 1694 payload_size = cluster_size * 5; 1695 1696 payload_read = malloc(payload_size); 1697 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 1698 1699 payload_write = malloc(payload_size); 1700 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 1701 1702 payload_pattern = malloc(payload_size); 1703 SPDK_CU_ASSERT_FATAL(payload_pattern != NULL); 1704 1705 /* Prepare random pattern to write */ 1706 memset(payload_pattern, 0xFF, payload_size); 1707 for (i = 0; i < pages_per_payload; i++) { 1708 *((uint64_t *)(payload_pattern + page_size * i)) = (i + 1); 1709 } 1710 1711 channel = spdk_bs_alloc_io_channel(bs); 1712 SPDK_CU_ASSERT_FATAL(channel != NULL); 1713 1714 /* Create blob */ 1715 ut_spdk_blob_opts_init(&opts); 1716 opts.thin_provision = false; 1717 opts.num_clusters = 5; 1718 1719 blob = ut_blob_create_and_open(bs, &opts); 1720 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 1721 1722 /* Initial read should return zeroed payload */ 1723 memset(payload_read, 0xFF, payload_size); 1724 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1725 poll_threads(); 1726 CU_ASSERT(g_bserrno == 0); 1727 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 1728 1729 /* Fill whole blob except last page */ 1730 spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload - 1, 1731 blob_op_complete, NULL); 1732 poll_threads(); 1733 CU_ASSERT(g_bserrno == 0); 1734 1735 /* Write last page with a pattern */ 1736 spdk_blob_io_write(blob, channel, payload_pattern, pages_per_payload - 1, 1, 1737 blob_op_complete, NULL); 1738 poll_threads(); 1739 CU_ASSERT(g_bserrno == 0); 1740 1741 /* Read whole blob and check consistency */ 1742 memset(payload_read, 0xFF, payload_size); 1743 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1744 poll_threads(); 1745 CU_ASSERT(g_bserrno == 0); 1746 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0); 1747 CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0); 1748 1749 /* Fill whole blob except first page */ 1750 spdk_blob_io_write(blob, channel, payload_pattern, 1, pages_per_payload - 1, 1751 blob_op_complete, NULL); 1752 poll_threads(); 1753 CU_ASSERT(g_bserrno == 0); 1754 1755 /* Write first page with a pattern */ 1756 spdk_blob_io_write(blob, channel, payload_pattern, 0, 1, 1757 blob_op_complete, NULL); 1758 poll_threads(); 1759 CU_ASSERT(g_bserrno == 0); 1760 1761 /* Read whole blob and check consistency */ 1762 memset(payload_read, 0xFF, payload_size); 1763 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1764 poll_threads(); 1765 CU_ASSERT(g_bserrno == 0); 1766 CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0); 1767 CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0); 1768 1769 1770 /* Fill whole blob with a pattern (5 clusters) */ 1771 1772 /* 1. Read test. */ 1773 _blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload, 1774 blob_op_complete, NULL); 1775 poll_threads(); 1776 CU_ASSERT(g_bserrno == 0); 1777 1778 memset(payload_read, 0xFF, payload_size); 1779 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1780 poll_threads(); 1781 poll_threads(); 1782 CU_ASSERT(g_bserrno == 0); 1783 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 1784 1785 /* 2. Write test. */ 1786 spdk_blob_io_write(blob, channel, payload_pattern, 0, pages_per_payload, 1787 blob_op_complete, NULL); 1788 poll_threads(); 1789 CU_ASSERT(g_bserrno == 0); 1790 1791 memset(payload_read, 0xFF, payload_size); 1792 _blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1793 poll_threads(); 1794 CU_ASSERT(g_bserrno == 0); 1795 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 1796 1797 spdk_bs_free_io_channel(channel); 1798 poll_threads(); 1799 1800 g_blob = NULL; 1801 g_blobid = 0; 1802 1803 free(payload_read); 1804 free(payload_write); 1805 free(payload_pattern); 1806 1807 ut_blob_close_and_delete(bs, blob); 1808 } 1809 1810 static void 1811 blob_operation_split_rw_iov(void) 1812 { 1813 struct spdk_blob_store *bs = g_bs; 1814 struct spdk_blob *blob; 1815 struct spdk_io_channel *channel; 1816 struct spdk_blob_opts opts; 1817 uint64_t cluster_size; 1818 1819 uint64_t payload_size; 1820 uint8_t *payload_read; 1821 uint8_t *payload_write; 1822 uint8_t *payload_pattern; 1823 1824 uint64_t page_size; 1825 uint64_t pages_per_cluster; 1826 uint64_t pages_per_payload; 1827 1828 struct iovec iov_read[2]; 1829 struct iovec iov_write[2]; 1830 1831 uint64_t i, j; 1832 1833 cluster_size = spdk_bs_get_cluster_size(bs); 1834 page_size = spdk_bs_get_page_size(bs); 1835 pages_per_cluster = cluster_size / page_size; 1836 pages_per_payload = pages_per_cluster * 5; 1837 payload_size = cluster_size * 5; 1838 1839 payload_read = malloc(payload_size); 1840 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 1841 1842 payload_write = malloc(payload_size); 1843 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 1844 1845 payload_pattern = malloc(payload_size); 1846 SPDK_CU_ASSERT_FATAL(payload_pattern != NULL); 1847 1848 /* Prepare random pattern to write */ 1849 for (i = 0; i < pages_per_payload; i++) { 1850 for (j = 0; j < page_size / sizeof(uint64_t); j++) { 1851 uint64_t *tmp; 1852 1853 tmp = (uint64_t *)payload_pattern; 1854 tmp += ((page_size * i) / sizeof(uint64_t)) + j; 1855 *tmp = i + 1; 1856 } 1857 } 1858 1859 channel = spdk_bs_alloc_io_channel(bs); 1860 SPDK_CU_ASSERT_FATAL(channel != NULL); 1861 1862 /* Create blob */ 1863 ut_spdk_blob_opts_init(&opts); 1864 opts.thin_provision = false; 1865 opts.num_clusters = 5; 1866 1867 blob = ut_blob_create_and_open(bs, &opts); 1868 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 1869 1870 /* Initial read should return zeroes payload */ 1871 memset(payload_read, 0xFF, payload_size); 1872 iov_read[0].iov_base = payload_read; 1873 iov_read[0].iov_len = cluster_size * 3; 1874 iov_read[1].iov_base = payload_read + cluster_size * 3; 1875 iov_read[1].iov_len = cluster_size * 2; 1876 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 1877 poll_threads(); 1878 CU_ASSERT(g_bserrno == 0); 1879 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 1880 1881 /* First of iovs fills whole blob except last page and second of iovs writes last page 1882 * with a pattern. */ 1883 iov_write[0].iov_base = payload_pattern; 1884 iov_write[0].iov_len = payload_size - page_size; 1885 iov_write[1].iov_base = payload_pattern; 1886 iov_write[1].iov_len = page_size; 1887 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 1888 poll_threads(); 1889 CU_ASSERT(g_bserrno == 0); 1890 1891 /* Read whole blob and check consistency */ 1892 memset(payload_read, 0xFF, payload_size); 1893 iov_read[0].iov_base = payload_read; 1894 iov_read[0].iov_len = cluster_size * 2; 1895 iov_read[1].iov_base = payload_read + cluster_size * 2; 1896 iov_read[1].iov_len = cluster_size * 3; 1897 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 1898 poll_threads(); 1899 CU_ASSERT(g_bserrno == 0); 1900 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0); 1901 CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0); 1902 1903 /* First of iovs fills only first page and second of iovs writes whole blob except 1904 * first page with a pattern. */ 1905 iov_write[0].iov_base = payload_pattern; 1906 iov_write[0].iov_len = page_size; 1907 iov_write[1].iov_base = payload_pattern; 1908 iov_write[1].iov_len = payload_size - page_size; 1909 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 1910 poll_threads(); 1911 CU_ASSERT(g_bserrno == 0); 1912 1913 /* Read whole blob and check consistency */ 1914 memset(payload_read, 0xFF, payload_size); 1915 iov_read[0].iov_base = payload_read; 1916 iov_read[0].iov_len = cluster_size * 4; 1917 iov_read[1].iov_base = payload_read + cluster_size * 4; 1918 iov_read[1].iov_len = cluster_size; 1919 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 1920 poll_threads(); 1921 CU_ASSERT(g_bserrno == 0); 1922 CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0); 1923 CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0); 1924 1925 1926 /* Fill whole blob with a pattern (5 clusters) */ 1927 1928 /* 1. Read test. */ 1929 _blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload, 1930 blob_op_complete, NULL); 1931 poll_threads(); 1932 CU_ASSERT(g_bserrno == 0); 1933 1934 memset(payload_read, 0xFF, payload_size); 1935 iov_read[0].iov_base = payload_read; 1936 iov_read[0].iov_len = cluster_size; 1937 iov_read[1].iov_base = payload_read + cluster_size; 1938 iov_read[1].iov_len = cluster_size * 4; 1939 spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL); 1940 poll_threads(); 1941 CU_ASSERT(g_bserrno == 0); 1942 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 1943 1944 /* 2. Write test. */ 1945 iov_write[0].iov_base = payload_read; 1946 iov_write[0].iov_len = cluster_size * 2; 1947 iov_write[1].iov_base = payload_read + cluster_size * 2; 1948 iov_write[1].iov_len = cluster_size * 3; 1949 spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL); 1950 poll_threads(); 1951 CU_ASSERT(g_bserrno == 0); 1952 1953 memset(payload_read, 0xFF, payload_size); 1954 _blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 1955 poll_threads(); 1956 CU_ASSERT(g_bserrno == 0); 1957 CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0); 1958 1959 spdk_bs_free_io_channel(channel); 1960 poll_threads(); 1961 1962 g_blob = NULL; 1963 g_blobid = 0; 1964 1965 free(payload_read); 1966 free(payload_write); 1967 free(payload_pattern); 1968 1969 ut_blob_close_and_delete(bs, blob); 1970 } 1971 1972 static void 1973 blob_unmap(void) 1974 { 1975 struct spdk_blob_store *bs = g_bs; 1976 struct spdk_blob *blob; 1977 struct spdk_io_channel *channel; 1978 struct spdk_blob_opts opts; 1979 uint8_t payload[4096]; 1980 int i; 1981 1982 channel = spdk_bs_alloc_io_channel(bs); 1983 CU_ASSERT(channel != NULL); 1984 1985 ut_spdk_blob_opts_init(&opts); 1986 opts.num_clusters = 10; 1987 1988 blob = ut_blob_create_and_open(bs, &opts); 1989 1990 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 1991 poll_threads(); 1992 CU_ASSERT(g_bserrno == 0); 1993 1994 memset(payload, 0, sizeof(payload)); 1995 payload[0] = 0xFF; 1996 1997 /* 1998 * Set first byte of every cluster to 0xFF. 1999 * First cluster on device is reserved so let's start from cluster number 1 2000 */ 2001 for (i = 1; i < 11; i++) { 2002 g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF; 2003 } 2004 2005 /* Confirm writes */ 2006 for (i = 0; i < 10; i++) { 2007 payload[0] = 0; 2008 spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1, 2009 blob_op_complete, NULL); 2010 poll_threads(); 2011 CU_ASSERT(g_bserrno == 0); 2012 CU_ASSERT(payload[0] == 0xFF); 2013 } 2014 2015 /* Mark some clusters as unallocated */ 2016 blob->active.clusters[1] = 0; 2017 blob->active.clusters[2] = 0; 2018 blob->active.clusters[3] = 0; 2019 blob->active.clusters[6] = 0; 2020 blob->active.clusters[8] = 0; 2021 2022 /* Unmap clusters by resizing to 0 */ 2023 spdk_blob_resize(blob, 0, blob_op_complete, NULL); 2024 poll_threads(); 2025 CU_ASSERT(g_bserrno == 0); 2026 2027 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2028 poll_threads(); 2029 CU_ASSERT(g_bserrno == 0); 2030 2031 /* Confirm that only 'allocated' clusters were unmapped */ 2032 for (i = 1; i < 11; i++) { 2033 switch (i) { 2034 case 2: 2035 case 3: 2036 case 4: 2037 case 7: 2038 case 9: 2039 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF); 2040 break; 2041 default: 2042 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0); 2043 break; 2044 } 2045 } 2046 2047 spdk_bs_free_io_channel(channel); 2048 poll_threads(); 2049 2050 ut_blob_close_and_delete(bs, blob); 2051 } 2052 2053 static void 2054 blob_iter(void) 2055 { 2056 struct spdk_blob_store *bs = g_bs; 2057 struct spdk_blob *blob; 2058 spdk_blob_id blobid; 2059 struct spdk_blob_opts blob_opts; 2060 2061 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 2062 poll_threads(); 2063 CU_ASSERT(g_blob == NULL); 2064 CU_ASSERT(g_bserrno == -ENOENT); 2065 2066 ut_spdk_blob_opts_init(&blob_opts); 2067 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 2068 poll_threads(); 2069 CU_ASSERT(g_bserrno == 0); 2070 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2071 blobid = g_blobid; 2072 2073 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 2074 poll_threads(); 2075 CU_ASSERT(g_blob != NULL); 2076 CU_ASSERT(g_bserrno == 0); 2077 blob = g_blob; 2078 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 2079 2080 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 2081 poll_threads(); 2082 CU_ASSERT(g_blob == NULL); 2083 CU_ASSERT(g_bserrno == -ENOENT); 2084 } 2085 2086 static void 2087 blob_xattr(void) 2088 { 2089 struct spdk_blob_store *bs = g_bs; 2090 struct spdk_blob *blob = g_blob; 2091 spdk_blob_id blobid = spdk_blob_get_id(blob); 2092 uint64_t length; 2093 int rc; 2094 const char *name1, *name2; 2095 const void *value; 2096 size_t value_len; 2097 struct spdk_xattr_names *names; 2098 2099 /* Test that set_xattr fails if md_ro flag is set. */ 2100 blob->md_ro = true; 2101 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2102 CU_ASSERT(rc == -EPERM); 2103 2104 blob->md_ro = false; 2105 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2106 CU_ASSERT(rc == 0); 2107 2108 length = 2345; 2109 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2110 CU_ASSERT(rc == 0); 2111 2112 /* Overwrite "length" xattr. */ 2113 length = 3456; 2114 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2115 CU_ASSERT(rc == 0); 2116 2117 /* get_xattr should still work even if md_ro flag is set. */ 2118 value = NULL; 2119 blob->md_ro = true; 2120 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2121 CU_ASSERT(rc == 0); 2122 SPDK_CU_ASSERT_FATAL(value != NULL); 2123 CU_ASSERT(*(uint64_t *)value == length); 2124 CU_ASSERT(value_len == 8); 2125 blob->md_ro = false; 2126 2127 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2128 CU_ASSERT(rc == -ENOENT); 2129 2130 names = NULL; 2131 rc = spdk_blob_get_xattr_names(blob, &names); 2132 CU_ASSERT(rc == 0); 2133 SPDK_CU_ASSERT_FATAL(names != NULL); 2134 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 2135 name1 = spdk_xattr_names_get_name(names, 0); 2136 SPDK_CU_ASSERT_FATAL(name1 != NULL); 2137 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 2138 name2 = spdk_xattr_names_get_name(names, 1); 2139 SPDK_CU_ASSERT_FATAL(name2 != NULL); 2140 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 2141 CU_ASSERT(strcmp(name1, name2)); 2142 spdk_xattr_names_free(names); 2143 2144 /* Confirm that remove_xattr fails if md_ro is set to true. */ 2145 blob->md_ro = true; 2146 rc = spdk_blob_remove_xattr(blob, "name"); 2147 CU_ASSERT(rc == -EPERM); 2148 2149 blob->md_ro = false; 2150 rc = spdk_blob_remove_xattr(blob, "name"); 2151 CU_ASSERT(rc == 0); 2152 2153 rc = spdk_blob_remove_xattr(blob, "foobar"); 2154 CU_ASSERT(rc == -ENOENT); 2155 2156 /* Set internal xattr */ 2157 length = 7898; 2158 rc = blob_set_xattr(blob, "internal", &length, sizeof(length), true); 2159 CU_ASSERT(rc == 0); 2160 rc = blob_get_xattr_value(blob, "internal", &value, &value_len, true); 2161 CU_ASSERT(rc == 0); 2162 CU_ASSERT(*(uint64_t *)value == length); 2163 /* try to get public xattr with same name */ 2164 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 2165 CU_ASSERT(rc != 0); 2166 rc = blob_get_xattr_value(blob, "internal", &value, &value_len, false); 2167 CU_ASSERT(rc != 0); 2168 /* Check if SPDK_BLOB_INTERNAL_XATTR is set */ 2169 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 2170 SPDK_BLOB_INTERNAL_XATTR); 2171 2172 spdk_blob_close(blob, blob_op_complete, NULL); 2173 poll_threads(); 2174 2175 /* Check if xattrs are persisted */ 2176 ut_bs_reload(&bs, NULL); 2177 2178 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2179 poll_threads(); 2180 CU_ASSERT(g_bserrno == 0); 2181 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2182 blob = g_blob; 2183 2184 rc = blob_get_xattr_value(blob, "internal", &value, &value_len, true); 2185 CU_ASSERT(rc == 0); 2186 CU_ASSERT(*(uint64_t *)value == length); 2187 2188 /* try to get internal xattr trough public call */ 2189 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 2190 CU_ASSERT(rc != 0); 2191 2192 rc = blob_remove_xattr(blob, "internal", true); 2193 CU_ASSERT(rc == 0); 2194 2195 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0); 2196 } 2197 2198 static void 2199 blob_parse_md(void) 2200 { 2201 struct spdk_blob_store *bs = g_bs; 2202 struct spdk_blob *blob; 2203 int rc; 2204 uint32_t used_pages; 2205 size_t xattr_length; 2206 char *xattr; 2207 2208 used_pages = spdk_bit_array_count_set(bs->used_md_pages); 2209 blob = ut_blob_create_and_open(bs, NULL); 2210 2211 /* Create large extent to force more than 1 page of metadata. */ 2212 xattr_length = SPDK_BS_MAX_DESC_SIZE - sizeof(struct spdk_blob_md_descriptor_xattr) - 2213 strlen("large_xattr"); 2214 xattr = calloc(xattr_length, sizeof(char)); 2215 SPDK_CU_ASSERT_FATAL(xattr != NULL); 2216 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); 2217 free(xattr); 2218 SPDK_CU_ASSERT_FATAL(rc == 0); 2219 2220 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2221 poll_threads(); 2222 2223 /* Delete the blob and verify that number of pages returned to before its creation. */ 2224 SPDK_CU_ASSERT_FATAL(used_pages != spdk_bit_array_count_set(bs->used_md_pages)); 2225 ut_blob_close_and_delete(bs, blob); 2226 SPDK_CU_ASSERT_FATAL(used_pages == spdk_bit_array_count_set(bs->used_md_pages)); 2227 } 2228 2229 static void 2230 bs_load(void) 2231 { 2232 struct spdk_blob_store *bs; 2233 struct spdk_bs_dev *dev; 2234 spdk_blob_id blobid; 2235 struct spdk_blob *blob; 2236 struct spdk_bs_super_block *super_block; 2237 uint64_t length; 2238 int rc; 2239 const void *value; 2240 size_t value_len; 2241 struct spdk_bs_opts opts; 2242 struct spdk_blob_opts blob_opts; 2243 2244 dev = init_dev(); 2245 spdk_bs_opts_init(&opts, sizeof(opts)); 2246 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2247 2248 /* Initialize a new blob store */ 2249 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2250 poll_threads(); 2251 CU_ASSERT(g_bserrno == 0); 2252 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2253 bs = g_bs; 2254 2255 /* Try to open a blobid that does not exist */ 2256 spdk_bs_open_blob(bs, 0, blob_op_with_handle_complete, NULL); 2257 poll_threads(); 2258 CU_ASSERT(g_bserrno == -ENOENT); 2259 CU_ASSERT(g_blob == NULL); 2260 2261 /* Create a blob */ 2262 blob = ut_blob_create_and_open(bs, NULL); 2263 blobid = spdk_blob_get_id(blob); 2264 2265 /* Try again to open valid blob but without the upper bit set */ 2266 spdk_bs_open_blob(bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 2267 poll_threads(); 2268 CU_ASSERT(g_bserrno == -ENOENT); 2269 CU_ASSERT(g_blob == NULL); 2270 2271 /* Set some xattrs */ 2272 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2273 CU_ASSERT(rc == 0); 2274 2275 length = 2345; 2276 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2277 CU_ASSERT(rc == 0); 2278 2279 /* Resize the blob */ 2280 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2281 poll_threads(); 2282 CU_ASSERT(g_bserrno == 0); 2283 2284 spdk_blob_close(blob, blob_op_complete, NULL); 2285 poll_threads(); 2286 CU_ASSERT(g_bserrno == 0); 2287 blob = NULL; 2288 g_blob = NULL; 2289 g_blobid = SPDK_BLOBID_INVALID; 2290 2291 /* Unload the blob store */ 2292 spdk_bs_unload(bs, bs_op_complete, NULL); 2293 poll_threads(); 2294 CU_ASSERT(g_bserrno == 0); 2295 g_bs = NULL; 2296 g_blob = NULL; 2297 g_blobid = 0; 2298 2299 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2300 CU_ASSERT(super_block->clean == 1); 2301 2302 /* Load should fail for device with an unsupported blocklen */ 2303 dev = init_dev(); 2304 dev->blocklen = SPDK_BS_PAGE_SIZE * 2; 2305 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2306 poll_threads(); 2307 CU_ASSERT(g_bserrno == -EINVAL); 2308 2309 /* Load should when max_md_ops is set to zero */ 2310 dev = init_dev(); 2311 spdk_bs_opts_init(&opts, sizeof(opts)); 2312 opts.max_md_ops = 0; 2313 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2314 poll_threads(); 2315 CU_ASSERT(g_bserrno == -EINVAL); 2316 2317 /* Load should when max_channel_ops is set to zero */ 2318 dev = init_dev(); 2319 spdk_bs_opts_init(&opts, sizeof(opts)); 2320 opts.max_channel_ops = 0; 2321 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2322 poll_threads(); 2323 CU_ASSERT(g_bserrno == -EINVAL); 2324 2325 /* Load an existing blob store */ 2326 dev = init_dev(); 2327 spdk_bs_opts_init(&opts, sizeof(opts)); 2328 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2329 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2330 poll_threads(); 2331 CU_ASSERT(g_bserrno == 0); 2332 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2333 bs = g_bs; 2334 2335 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2336 CU_ASSERT(super_block->clean == 1); 2337 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2338 2339 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2340 poll_threads(); 2341 CU_ASSERT(g_bserrno == 0); 2342 CU_ASSERT(g_blob != NULL); 2343 blob = g_blob; 2344 2345 /* Verify that blobstore is marked dirty after first metadata sync */ 2346 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2347 CU_ASSERT(super_block->clean == 1); 2348 2349 /* Get the xattrs */ 2350 value = NULL; 2351 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2352 CU_ASSERT(rc == 0); 2353 SPDK_CU_ASSERT_FATAL(value != NULL); 2354 CU_ASSERT(*(uint64_t *)value == length); 2355 CU_ASSERT(value_len == 8); 2356 2357 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2358 CU_ASSERT(rc == -ENOENT); 2359 2360 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2361 2362 spdk_blob_close(blob, blob_op_complete, NULL); 2363 poll_threads(); 2364 CU_ASSERT(g_bserrno == 0); 2365 blob = NULL; 2366 g_blob = NULL; 2367 2368 spdk_bs_unload(bs, bs_op_complete, NULL); 2369 poll_threads(); 2370 CU_ASSERT(g_bserrno == 0); 2371 g_bs = NULL; 2372 2373 /* Load should fail: bdev size < saved size */ 2374 dev = init_dev(); 2375 dev->blockcnt /= 2; 2376 2377 spdk_bs_opts_init(&opts, sizeof(opts)); 2378 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2379 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2380 poll_threads(); 2381 2382 CU_ASSERT(g_bserrno == -EILSEQ); 2383 2384 /* Load should succeed: bdev size > saved size */ 2385 dev = init_dev(); 2386 dev->blockcnt *= 4; 2387 2388 spdk_bs_opts_init(&opts, sizeof(opts)); 2389 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2390 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2391 poll_threads(); 2392 CU_ASSERT(g_bserrno == 0); 2393 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2394 bs = g_bs; 2395 2396 CU_ASSERT(g_bserrno == 0); 2397 spdk_bs_unload(bs, bs_op_complete, NULL); 2398 poll_threads(); 2399 2400 2401 /* Test compatibility mode */ 2402 2403 dev = init_dev(); 2404 super_block->size = 0; 2405 super_block->crc = blob_md_page_calc_crc(super_block); 2406 2407 spdk_bs_opts_init(&opts, sizeof(opts)); 2408 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2409 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2410 poll_threads(); 2411 CU_ASSERT(g_bserrno == 0); 2412 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2413 bs = g_bs; 2414 2415 /* Create a blob */ 2416 ut_spdk_blob_opts_init(&blob_opts); 2417 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 2418 poll_threads(); 2419 CU_ASSERT(g_bserrno == 0); 2420 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2421 2422 /* Blobstore should update number of blocks in super_block */ 2423 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2424 CU_ASSERT(super_block->clean == 0); 2425 2426 spdk_bs_unload(bs, bs_op_complete, NULL); 2427 poll_threads(); 2428 CU_ASSERT(g_bserrno == 0); 2429 CU_ASSERT(super_block->clean == 1); 2430 g_bs = NULL; 2431 2432 } 2433 2434 static void 2435 bs_load_pending_removal(void) 2436 { 2437 struct spdk_blob_store *bs = g_bs; 2438 struct spdk_blob_opts opts; 2439 struct spdk_blob *blob, *snapshot; 2440 spdk_blob_id blobid, snapshotid; 2441 const void *value; 2442 size_t value_len; 2443 int rc; 2444 2445 /* Create blob */ 2446 ut_spdk_blob_opts_init(&opts); 2447 opts.num_clusters = 10; 2448 2449 blob = ut_blob_create_and_open(bs, &opts); 2450 blobid = spdk_blob_get_id(blob); 2451 2452 /* Create snapshot */ 2453 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 2454 poll_threads(); 2455 CU_ASSERT(g_bserrno == 0); 2456 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2457 snapshotid = g_blobid; 2458 2459 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 2460 poll_threads(); 2461 CU_ASSERT(g_bserrno == 0); 2462 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2463 snapshot = g_blob; 2464 2465 /* Set SNAPSHOT_PENDING_REMOVAL xattr */ 2466 snapshot->md_ro = false; 2467 rc = blob_set_xattr(snapshot, SNAPSHOT_PENDING_REMOVAL, &blobid, sizeof(spdk_blob_id), true); 2468 CU_ASSERT(rc == 0); 2469 snapshot->md_ro = true; 2470 2471 spdk_blob_close(snapshot, blob_op_complete, NULL); 2472 poll_threads(); 2473 CU_ASSERT(g_bserrno == 0); 2474 2475 spdk_blob_close(blob, blob_op_complete, NULL); 2476 poll_threads(); 2477 CU_ASSERT(g_bserrno == 0); 2478 2479 /* Reload blobstore */ 2480 ut_bs_reload(&bs, NULL); 2481 2482 /* Snapshot should not be removed as blob is still pointing to it */ 2483 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 2484 poll_threads(); 2485 CU_ASSERT(g_bserrno == 0); 2486 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2487 snapshot = g_blob; 2488 2489 /* SNAPSHOT_PENDING_REMOVAL xattr should be removed during load */ 2490 rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_PENDING_REMOVAL, &value, &value_len); 2491 CU_ASSERT(rc != 0); 2492 2493 /* Set SNAPSHOT_PENDING_REMOVAL xattr again */ 2494 snapshot->md_ro = false; 2495 rc = blob_set_xattr(snapshot, SNAPSHOT_PENDING_REMOVAL, &blobid, sizeof(spdk_blob_id), true); 2496 CU_ASSERT(rc == 0); 2497 snapshot->md_ro = true; 2498 2499 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2500 poll_threads(); 2501 CU_ASSERT(g_bserrno == 0); 2502 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2503 blob = g_blob; 2504 2505 /* Remove parent_id from blob by removing BLOB_SNAPSHOT xattr */ 2506 blob_remove_xattr(blob, BLOB_SNAPSHOT, true); 2507 2508 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2509 poll_threads(); 2510 CU_ASSERT(g_bserrno == 0); 2511 2512 spdk_blob_close(snapshot, blob_op_complete, NULL); 2513 poll_threads(); 2514 CU_ASSERT(g_bserrno == 0); 2515 2516 spdk_blob_close(blob, blob_op_complete, NULL); 2517 poll_threads(); 2518 CU_ASSERT(g_bserrno == 0); 2519 2520 /* Reload blobstore */ 2521 ut_bs_reload(&bs, NULL); 2522 2523 /* Snapshot should be removed as blob is not pointing to it anymore */ 2524 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 2525 poll_threads(); 2526 CU_ASSERT(g_bserrno != 0); 2527 } 2528 2529 static void 2530 bs_load_custom_cluster_size(void) 2531 { 2532 struct spdk_blob_store *bs; 2533 struct spdk_bs_dev *dev; 2534 struct spdk_bs_super_block *super_block; 2535 struct spdk_bs_opts opts; 2536 uint32_t custom_cluster_size = 4194304; /* 4MiB */ 2537 uint32_t cluster_sz; 2538 uint64_t total_clusters; 2539 2540 dev = init_dev(); 2541 spdk_bs_opts_init(&opts, sizeof(opts)); 2542 opts.cluster_sz = custom_cluster_size; 2543 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2544 2545 /* Initialize a new blob store */ 2546 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2547 poll_threads(); 2548 CU_ASSERT(g_bserrno == 0); 2549 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2550 bs = g_bs; 2551 cluster_sz = bs->cluster_sz; 2552 total_clusters = bs->total_clusters; 2553 2554 /* Unload the blob store */ 2555 spdk_bs_unload(bs, bs_op_complete, NULL); 2556 poll_threads(); 2557 CU_ASSERT(g_bserrno == 0); 2558 g_bs = NULL; 2559 g_blob = NULL; 2560 g_blobid = 0; 2561 2562 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2563 CU_ASSERT(super_block->clean == 1); 2564 2565 /* Load an existing blob store */ 2566 dev = init_dev(); 2567 spdk_bs_opts_init(&opts, sizeof(opts)); 2568 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2569 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2570 poll_threads(); 2571 CU_ASSERT(g_bserrno == 0); 2572 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2573 bs = g_bs; 2574 /* Compare cluster size and number to one after initialization */ 2575 CU_ASSERT(cluster_sz == bs->cluster_sz); 2576 CU_ASSERT(total_clusters == bs->total_clusters); 2577 2578 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2579 CU_ASSERT(super_block->clean == 1); 2580 CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen); 2581 2582 spdk_bs_unload(bs, bs_op_complete, NULL); 2583 poll_threads(); 2584 CU_ASSERT(g_bserrno == 0); 2585 CU_ASSERT(super_block->clean == 1); 2586 g_bs = NULL; 2587 } 2588 2589 static void 2590 bs_load_after_failed_grow(void) 2591 { 2592 struct spdk_blob_store *bs; 2593 struct spdk_bs_dev *dev; 2594 struct spdk_bs_super_block *super_block; 2595 struct spdk_bs_opts opts; 2596 struct spdk_bs_md_mask *mask; 2597 struct spdk_blob_opts blob_opts; 2598 struct spdk_blob *blob, *snapshot; 2599 spdk_blob_id blobid, snapshotid; 2600 uint64_t total_data_clusters; 2601 2602 dev = init_dev(); 2603 spdk_bs_opts_init(&opts, sizeof(opts)); 2604 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2605 /* 2606 * The bdev_size is 64M, cluster_sz is 1M, so there are 64 clusters. The 2607 * blobstore will create 64 md pages by default. We set num_md_pages to 128, 2608 * thus the blobstore could grow to the double size. 2609 */ 2610 opts.num_md_pages = 128; 2611 2612 /* Initialize a new blob store */ 2613 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2614 poll_threads(); 2615 CU_ASSERT(g_bserrno == 0); 2616 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2617 bs = g_bs; 2618 2619 /* Create blob */ 2620 ut_spdk_blob_opts_init(&blob_opts); 2621 blob_opts.num_clusters = 10; 2622 2623 blob = ut_blob_create_and_open(bs, &blob_opts); 2624 blobid = spdk_blob_get_id(blob); 2625 2626 /* Create snapshot */ 2627 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 2628 poll_threads(); 2629 CU_ASSERT(g_bserrno == 0); 2630 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2631 snapshotid = g_blobid; 2632 2633 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 2634 poll_threads(); 2635 CU_ASSERT(g_bserrno == 0); 2636 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2637 snapshot = g_blob; 2638 2639 spdk_blob_close(snapshot, blob_op_complete, NULL); 2640 poll_threads(); 2641 CU_ASSERT(g_bserrno == 0); 2642 2643 spdk_blob_close(blob, blob_op_complete, NULL); 2644 poll_threads(); 2645 CU_ASSERT(g_bserrno == 0); 2646 2647 total_data_clusters = bs->total_data_clusters; 2648 CU_ASSERT(bs->num_free_clusters + 10 == total_data_clusters); 2649 2650 /* Unload the blob store */ 2651 spdk_bs_unload(bs, bs_op_complete, NULL); 2652 poll_threads(); 2653 CU_ASSERT(g_bserrno == 0); 2654 g_bs = NULL; 2655 g_blob = NULL; 2656 g_blobid = 0; 2657 2658 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2659 CU_ASSERT(super_block->clean == 1); 2660 2661 mask = (struct spdk_bs_md_mask *)(g_dev_buffer + super_block->used_cluster_mask_start * 4096); 2662 CU_ASSERT(mask->type == SPDK_MD_MASK_TYPE_USED_CLUSTERS); 2663 CU_ASSERT(mask->length == super_block->size / super_block->cluster_size); 2664 2665 /* 2666 * We change the mask->length to emulate this scenario: A spdk_bs_grow failed after it changed 2667 * the used_cluster bitmap length, but it didn't change the super block yet. 2668 */ 2669 mask->length *= 2; 2670 2671 /* Load an existing blob store */ 2672 dev = init_dev(); 2673 dev->blockcnt *= 2; 2674 spdk_bs_opts_init(&opts, sizeof(opts)); 2675 opts.clear_method = BS_CLEAR_WITH_NONE; 2676 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2677 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2678 poll_threads(); 2679 CU_ASSERT(g_bserrno == 0); 2680 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2681 bs = g_bs; 2682 2683 /* Check the capacity is the same as before */ 2684 CU_ASSERT(bs->total_data_clusters == total_data_clusters); 2685 CU_ASSERT(bs->num_free_clusters + 10 == total_data_clusters); 2686 2687 /* Check the blob and the snapshot are still available */ 2688 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2689 poll_threads(); 2690 CU_ASSERT(g_bserrno == 0); 2691 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2692 blob = g_blob; 2693 2694 spdk_blob_close(blob, blob_op_complete, NULL); 2695 poll_threads(); 2696 CU_ASSERT(g_bserrno == 0); 2697 2698 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 2699 poll_threads(); 2700 CU_ASSERT(g_bserrno == 0); 2701 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2702 snapshot = g_blob; 2703 2704 spdk_blob_close(snapshot, blob_op_complete, NULL); 2705 poll_threads(); 2706 CU_ASSERT(g_bserrno == 0); 2707 2708 spdk_bs_unload(bs, bs_op_complete, NULL); 2709 poll_threads(); 2710 CU_ASSERT(g_bserrno == 0); 2711 CU_ASSERT(super_block->clean == 1); 2712 g_bs = NULL; 2713 } 2714 2715 static void 2716 bs_type(void) 2717 { 2718 struct spdk_blob_store *bs; 2719 struct spdk_bs_dev *dev; 2720 struct spdk_bs_opts opts; 2721 2722 dev = init_dev(); 2723 spdk_bs_opts_init(&opts, sizeof(opts)); 2724 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2725 2726 /* Initialize a new blob store */ 2727 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2728 poll_threads(); 2729 CU_ASSERT(g_bserrno == 0); 2730 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2731 bs = g_bs; 2732 2733 /* Unload the blob store */ 2734 spdk_bs_unload(bs, bs_op_complete, NULL); 2735 poll_threads(); 2736 CU_ASSERT(g_bserrno == 0); 2737 g_bs = NULL; 2738 g_blob = NULL; 2739 g_blobid = 0; 2740 2741 /* Load non existing blobstore type */ 2742 dev = init_dev(); 2743 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 2744 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2745 poll_threads(); 2746 CU_ASSERT(g_bserrno != 0); 2747 2748 /* Load with empty blobstore type */ 2749 dev = init_dev(); 2750 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2751 spdk_bs_load(dev, &opts, 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 spdk_bs_unload(bs, bs_op_complete, NULL); 2758 poll_threads(); 2759 CU_ASSERT(g_bserrno == 0); 2760 g_bs = NULL; 2761 2762 /* Initialize a new blob store with empty bstype */ 2763 dev = init_dev(); 2764 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2765 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2766 poll_threads(); 2767 CU_ASSERT(g_bserrno == 0); 2768 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2769 bs = g_bs; 2770 2771 spdk_bs_unload(bs, bs_op_complete, NULL); 2772 poll_threads(); 2773 CU_ASSERT(g_bserrno == 0); 2774 g_bs = NULL; 2775 2776 /* Load non existing blobstore type */ 2777 dev = init_dev(); 2778 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 2779 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2780 poll_threads(); 2781 CU_ASSERT(g_bserrno != 0); 2782 2783 /* Load with empty blobstore type */ 2784 dev = init_dev(); 2785 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2786 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2787 poll_threads(); 2788 CU_ASSERT(g_bserrno == 0); 2789 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2790 bs = g_bs; 2791 2792 spdk_bs_unload(bs, bs_op_complete, NULL); 2793 poll_threads(); 2794 CU_ASSERT(g_bserrno == 0); 2795 g_bs = NULL; 2796 } 2797 2798 static void 2799 bs_super_block(void) 2800 { 2801 struct spdk_blob_store *bs; 2802 struct spdk_bs_dev *dev; 2803 struct spdk_bs_super_block *super_block; 2804 struct spdk_bs_opts opts; 2805 struct spdk_bs_super_block_ver1 super_block_v1; 2806 2807 dev = init_dev(); 2808 spdk_bs_opts_init(&opts, sizeof(opts)); 2809 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2810 2811 /* Initialize a new blob store */ 2812 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2813 poll_threads(); 2814 CU_ASSERT(g_bserrno == 0); 2815 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2816 bs = g_bs; 2817 2818 /* Unload the blob store */ 2819 spdk_bs_unload(bs, bs_op_complete, NULL); 2820 poll_threads(); 2821 CU_ASSERT(g_bserrno == 0); 2822 g_bs = NULL; 2823 g_blob = NULL; 2824 g_blobid = 0; 2825 2826 /* Load an existing blob store with version newer than supported */ 2827 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2828 super_block->version++; 2829 2830 dev = init_dev(); 2831 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2832 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2833 poll_threads(); 2834 CU_ASSERT(g_bserrno != 0); 2835 2836 /* Create a new blob store with super block version 1 */ 2837 dev = init_dev(); 2838 super_block_v1.version = 1; 2839 memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 2840 super_block_v1.length = 0x1000; 2841 super_block_v1.clean = 1; 2842 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 2843 super_block_v1.cluster_size = 0x100000; 2844 super_block_v1.used_page_mask_start = 0x01; 2845 super_block_v1.used_page_mask_len = 0x01; 2846 super_block_v1.used_cluster_mask_start = 0x02; 2847 super_block_v1.used_cluster_mask_len = 0x01; 2848 super_block_v1.md_start = 0x03; 2849 super_block_v1.md_len = 0x40; 2850 memset(super_block_v1.reserved, 0, 4036); 2851 super_block_v1.crc = blob_md_page_calc_crc(&super_block_v1); 2852 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 2853 2854 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2855 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2856 poll_threads(); 2857 CU_ASSERT(g_bserrno == 0); 2858 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2859 bs = g_bs; 2860 2861 spdk_bs_unload(bs, bs_op_complete, NULL); 2862 poll_threads(); 2863 CU_ASSERT(g_bserrno == 0); 2864 g_bs = NULL; 2865 } 2866 2867 static void 2868 bs_test_recover_cluster_count(void) 2869 { 2870 struct spdk_blob_store *bs; 2871 struct spdk_bs_dev *dev; 2872 struct spdk_bs_super_block super_block; 2873 struct spdk_bs_opts opts; 2874 2875 dev = init_dev(); 2876 spdk_bs_opts_init(&opts, sizeof(opts)); 2877 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2878 2879 super_block.version = 3; 2880 memcpy(super_block.signature, "SPDKBLOB", sizeof(super_block.signature)); 2881 super_block.length = 0x1000; 2882 super_block.clean = 0; 2883 super_block.super_blob = 0xFFFFFFFFFFFFFFFF; 2884 super_block.cluster_size = 4096; 2885 super_block.used_page_mask_start = 0x01; 2886 super_block.used_page_mask_len = 0x01; 2887 super_block.used_cluster_mask_start = 0x02; 2888 super_block.used_cluster_mask_len = 0x01; 2889 super_block.used_blobid_mask_start = 0x03; 2890 super_block.used_blobid_mask_len = 0x01; 2891 super_block.md_start = 0x04; 2892 super_block.md_len = 0x40; 2893 memset(super_block.bstype.bstype, 0, sizeof(super_block.bstype.bstype)); 2894 super_block.size = dev->blockcnt * dev->blocklen; 2895 super_block.io_unit_size = 0x1000; 2896 memset(super_block.reserved, 0, 4000); 2897 super_block.crc = blob_md_page_calc_crc(&super_block); 2898 memcpy(g_dev_buffer, &super_block, sizeof(struct spdk_bs_super_block)); 2899 2900 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2901 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2902 poll_threads(); 2903 CU_ASSERT(g_bserrno == 0); 2904 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2905 bs = g_bs; 2906 CU_ASSERT(bs->num_free_clusters == bs->total_clusters - (super_block.md_start + 2907 super_block.md_len)); 2908 2909 spdk_bs_unload(bs, bs_op_complete, NULL); 2910 poll_threads(); 2911 CU_ASSERT(g_bserrno == 0); 2912 g_bs = NULL; 2913 } 2914 2915 static void 2916 bs_grow_live(void) 2917 { 2918 struct spdk_blob_store *bs; 2919 struct spdk_bs_dev *dev; 2920 struct spdk_bs_super_block super_block; 2921 struct spdk_bs_opts opts; 2922 struct spdk_bs_md_mask mask; 2923 uint64_t bdev_size; 2924 uint64_t total_data_clusters; 2925 2926 /* 2927 * Further down the test the dev size will be larger than the g_dev_buffer size, 2928 * so we set clear_method to NONE, or the blobstore will try to clear the dev and 2929 * will write beyond the end of g_dev_buffer. 2930 */ 2931 dev = init_dev(); 2932 spdk_bs_opts_init(&opts, sizeof(opts)); 2933 opts.clear_method = BS_CLEAR_WITH_NONE; 2934 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2935 poll_threads(); 2936 CU_ASSERT(g_bserrno == 0); 2937 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2938 bs = g_bs; 2939 CU_ASSERT(spdk_bs_total_data_cluster_count(bs) == 63); 2940 2941 /* 2942 * The default dev size is 64M, here we set the dev size to 128M, 2943 * then the blobstore will adjust the metadata according to the new size. 2944 */ 2945 dev->blockcnt = (128L * 1024L * 1024L) / dev->blocklen; 2946 bdev_size = dev->blockcnt * dev->blocklen; 2947 spdk_bs_grow_live(bs, bs_op_complete, NULL); 2948 poll_threads(); 2949 CU_ASSERT(g_bserrno == 0); 2950 total_data_clusters = spdk_bs_total_data_cluster_count(bs); 2951 CU_ASSERT(total_data_clusters == 127); 2952 2953 /* Make sure the super block is updated. */ 2954 memcpy(&super_block, g_dev_buffer, sizeof(struct spdk_bs_super_block)); 2955 CU_ASSERT(super_block.size == bdev_size); 2956 CU_ASSERT(super_block.clean == 0); 2957 /* The used_cluster mask is not written out until first spdk_bs_unload. */ 2958 memcpy(&mask, g_dev_buffer + super_block.used_cluster_mask_start * 4096, 2959 sizeof(struct spdk_bs_md_mask)); 2960 CU_ASSERT(mask.type == 0); 2961 CU_ASSERT(mask.length == 0); 2962 2963 spdk_bs_unload(bs, bs_op_complete, NULL); 2964 poll_threads(); 2965 CU_ASSERT(g_bserrno == 0); 2966 g_bs = NULL; 2967 2968 /* Make sure all metadata is correct, super block and used_cluster mask. */ 2969 memcpy(&super_block, g_dev_buffer, sizeof(struct spdk_bs_super_block)); 2970 CU_ASSERT(super_block.size == bdev_size); 2971 CU_ASSERT(super_block.clean == 1); 2972 memcpy(&mask, g_dev_buffer + super_block.used_cluster_mask_start * 4096, 2973 sizeof(struct spdk_bs_md_mask)); 2974 CU_ASSERT(mask.type == SPDK_MD_MASK_TYPE_USED_CLUSTERS); 2975 CU_ASSERT(mask.length == bdev_size / (1 * 1024 * 1024)); 2976 2977 /* Load blobstore and check the cluster counts again. */ 2978 dev = init_dev(); 2979 dev->blockcnt = (128L * 1024L * 1024L) / dev->blocklen; 2980 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2981 poll_threads(); 2982 CU_ASSERT(g_bserrno == 0); 2983 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2984 CU_ASSERT(super_block.clean == 1); 2985 bs = g_bs; 2986 CU_ASSERT(total_data_clusters == spdk_bs_total_data_cluster_count(bs)); 2987 2988 /* Perform grow without change in size, expected pass. */ 2989 spdk_bs_grow_live(bs, bs_op_complete, NULL); 2990 poll_threads(); 2991 CU_ASSERT(g_bserrno == 0); 2992 CU_ASSERT(total_data_clusters == spdk_bs_total_data_cluster_count(bs)); 2993 memcpy(&super_block, g_dev_buffer, sizeof(struct spdk_bs_super_block)); 2994 CU_ASSERT(super_block.size == bdev_size); 2995 CU_ASSERT(super_block.clean == 1); 2996 2997 spdk_bs_unload(bs, bs_op_complete, NULL); 2998 poll_threads(); 2999 CU_ASSERT(g_bserrno == 0); 3000 g_bs = NULL; 3001 } 3002 3003 static void 3004 bs_grow_live_no_space(void) 3005 { 3006 struct spdk_blob_store *bs; 3007 struct spdk_bs_dev *dev; 3008 struct spdk_bs_super_block super_block; 3009 struct spdk_bs_opts opts; 3010 struct spdk_bs_md_mask mask; 3011 uint64_t bdev_size_init; 3012 uint64_t total_data_clusters, max_clusters; 3013 3014 /* 3015 * Further down the test the dev size will be larger than the g_dev_buffer size, 3016 * so we set clear_method to NONE, or the blobstore will try to clear the dev and 3017 * will write beyond the end of g_dev_buffer. 3018 */ 3019 dev = init_dev(); 3020 bdev_size_init = dev->blockcnt * dev->blocklen; 3021 spdk_bs_opts_init(&opts, sizeof(opts)); 3022 opts.clear_method = BS_CLEAR_WITH_NONE; 3023 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3024 poll_threads(); 3025 CU_ASSERT(g_bserrno == 0); 3026 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3027 bs = g_bs; 3028 total_data_clusters = spdk_bs_total_data_cluster_count(bs); 3029 CU_ASSERT(total_data_clusters == 63); 3030 3031 /* 3032 * The default dev size is 64M, here we set the dev size to 32M, 3033 * expecting EILSEQ due to super_block validation and no change in blobstore. 3034 */ 3035 dev->blockcnt = (32L * 1024L * 1024L) / dev->blocklen; 3036 spdk_bs_grow_live(bs, bs_op_complete, NULL); 3037 poll_threads(); 3038 /* This error code comes from bs_super_validate() */ 3039 CU_ASSERT(g_bserrno == -EILSEQ); 3040 CU_ASSERT(total_data_clusters == spdk_bs_total_data_cluster_count(bs)); 3041 memcpy(&super_block, g_dev_buffer, sizeof(struct spdk_bs_super_block)); 3042 CU_ASSERT(super_block.size == bdev_size_init); 3043 3044 /* 3045 * Blobstore in this test has only space for single md_page for used_clusters, 3046 * which fits 1 bit per cluster minus the md header. 3047 * 3048 * Dev size is increased to exceed the reserved space for the used_cluster_mask 3049 * in the metadata, expecting ENOSPC and no change in blobstore. 3050 */ 3051 max_clusters = (spdk_bs_get_page_size(bs) - sizeof(struct spdk_bs_md_mask)) * 8; 3052 max_clusters += 1; 3053 dev->blockcnt = (max_clusters * spdk_bs_get_cluster_size(bs)) / dev->blocklen; 3054 spdk_bs_grow_live(bs, bs_op_complete, NULL); 3055 poll_threads(); 3056 CU_ASSERT(g_bserrno == -ENOSPC); 3057 CU_ASSERT(total_data_clusters == spdk_bs_total_data_cluster_count(bs)); 3058 memcpy(&super_block, g_dev_buffer, sizeof(struct spdk_bs_super_block)); 3059 CU_ASSERT(super_block.size == bdev_size_init); 3060 3061 /* 3062 * No change should have occurred for the duration of the test, 3063 * unload blobstore and check metadata. 3064 */ 3065 spdk_bs_unload(bs, bs_op_complete, NULL); 3066 poll_threads(); 3067 CU_ASSERT(g_bserrno == 0); 3068 g_bs = NULL; 3069 3070 /* Make sure all metadata is correct, super block and used_cluster mask. */ 3071 memcpy(&super_block, g_dev_buffer, sizeof(struct spdk_bs_super_block)); 3072 CU_ASSERT(super_block.size == bdev_size_init); 3073 CU_ASSERT(super_block.clean == 1); 3074 memcpy(&mask, g_dev_buffer + super_block.used_cluster_mask_start * 4096, 3075 sizeof(struct spdk_bs_md_mask)); 3076 CU_ASSERT(mask.type == SPDK_MD_MASK_TYPE_USED_CLUSTERS); 3077 CU_ASSERT(mask.length == bdev_size_init / (1 * 1024 * 1024)); 3078 3079 /* Load blobstore and check the cluster counts again. */ 3080 dev = init_dev(); 3081 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3082 poll_threads(); 3083 CU_ASSERT(g_bserrno == 0); 3084 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3085 bs = g_bs; 3086 CU_ASSERT(total_data_clusters == spdk_bs_total_data_cluster_count(bs)); 3087 3088 spdk_bs_unload(bs, bs_op_complete, NULL); 3089 poll_threads(); 3090 CU_ASSERT(g_bserrno == 0); 3091 g_bs = NULL; 3092 } 3093 3094 static void 3095 bs_test_grow(void) 3096 { 3097 struct spdk_blob_store *bs; 3098 struct spdk_bs_dev *dev; 3099 struct spdk_bs_super_block super_block; 3100 struct spdk_bs_opts opts; 3101 struct spdk_bs_md_mask mask; 3102 uint64_t bdev_size; 3103 3104 dev = init_dev(); 3105 bdev_size = dev->blockcnt * dev->blocklen; 3106 spdk_bs_opts_init(&opts, sizeof(opts)); 3107 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3108 poll_threads(); 3109 CU_ASSERT(g_bserrno == 0); 3110 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3111 bs = g_bs; 3112 3113 spdk_bs_unload(bs, bs_op_complete, NULL); 3114 poll_threads(); 3115 CU_ASSERT(g_bserrno == 0); 3116 g_bs = NULL; 3117 3118 /* 3119 * To make sure all the metadata are updated to the disk, 3120 * we check the g_dev_buffer after spdk_bs_unload. 3121 */ 3122 memcpy(&super_block, g_dev_buffer, sizeof(struct spdk_bs_super_block)); 3123 CU_ASSERT(super_block.size == bdev_size); 3124 3125 /* 3126 * Make sure the used_cluster mask is correct. 3127 */ 3128 memcpy(&mask, g_dev_buffer + super_block.used_cluster_mask_start * 4096, 3129 sizeof(struct spdk_bs_md_mask)); 3130 CU_ASSERT(mask.type == SPDK_MD_MASK_TYPE_USED_CLUSTERS); 3131 CU_ASSERT(mask.length == bdev_size / (1 * 1024 * 1024)); 3132 3133 /* 3134 * The default dev size is 64M, here we set the dev size to 128M, 3135 * then the blobstore will adjust the metadata according to the new size. 3136 * The dev size is larger than the g_dev_buffer size, so we set clear_method 3137 * to NONE, or the blobstore will try to clear the dev and will write beyond 3138 * the end of g_dev_buffer. 3139 */ 3140 dev = init_dev(); 3141 dev->blockcnt = (128L * 1024L * 1024L) / dev->blocklen; 3142 bdev_size = dev->blockcnt * dev->blocklen; 3143 spdk_bs_opts_init(&opts, sizeof(opts)); 3144 opts.clear_method = BS_CLEAR_WITH_NONE; 3145 spdk_bs_grow(dev, &opts, bs_op_with_handle_complete, NULL); 3146 poll_threads(); 3147 CU_ASSERT(g_bserrno == 0); 3148 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3149 bs = g_bs; 3150 3151 /* 3152 * After spdk_bs_grow, all metadata are updated to the disk. 3153 * So we can check g_dev_buffer now. 3154 */ 3155 memcpy(&super_block, g_dev_buffer, sizeof(struct spdk_bs_super_block)); 3156 CU_ASSERT(super_block.size == bdev_size); 3157 3158 /* 3159 * Make sure the used_cluster mask has been updated according to the bdev size 3160 */ 3161 memcpy(&mask, g_dev_buffer + super_block.used_cluster_mask_start * 4096, 3162 sizeof(struct spdk_bs_md_mask)); 3163 CU_ASSERT(mask.type == SPDK_MD_MASK_TYPE_USED_CLUSTERS); 3164 CU_ASSERT(mask.length == bdev_size / (1 * 1024 * 1024)); 3165 3166 spdk_bs_unload(bs, bs_op_complete, NULL); 3167 poll_threads(); 3168 CU_ASSERT(g_bserrno == 0); 3169 g_bs = NULL; 3170 } 3171 3172 /* 3173 * Create a blobstore and then unload it. 3174 */ 3175 static void 3176 bs_unload(void) 3177 { 3178 struct spdk_blob_store *bs = g_bs; 3179 struct spdk_blob *blob; 3180 3181 /* Create a blob and open it. */ 3182 blob = ut_blob_create_and_open(bs, NULL); 3183 3184 /* Try to unload blobstore, should fail with open blob */ 3185 g_bserrno = -1; 3186 spdk_bs_unload(bs, bs_op_complete, NULL); 3187 poll_threads(); 3188 CU_ASSERT(g_bserrno == -EBUSY); 3189 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3190 3191 /* Close the blob, then successfully unload blobstore */ 3192 g_bserrno = -1; 3193 spdk_blob_close(blob, blob_op_complete, NULL); 3194 poll_threads(); 3195 CU_ASSERT(g_bserrno == 0); 3196 } 3197 3198 /* 3199 * Create a blobstore with a cluster size different than the default, and ensure it is 3200 * persisted. 3201 */ 3202 static void 3203 bs_cluster_sz(void) 3204 { 3205 struct spdk_blob_store *bs; 3206 struct spdk_bs_dev *dev; 3207 struct spdk_bs_opts opts; 3208 uint32_t cluster_sz; 3209 3210 /* Set cluster size to zero */ 3211 dev = init_dev(); 3212 spdk_bs_opts_init(&opts, sizeof(opts)); 3213 opts.cluster_sz = 0; 3214 3215 /* Initialize a new blob store */ 3216 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3217 poll_threads(); 3218 CU_ASSERT(g_bserrno == -EINVAL); 3219 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 3220 3221 /* 3222 * Set cluster size to blobstore page size, 3223 * to work it is required to be at least twice the blobstore page size. 3224 */ 3225 dev = init_dev(); 3226 spdk_bs_opts_init(&opts, sizeof(opts)); 3227 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 3228 3229 /* Initialize a new blob store */ 3230 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3231 poll_threads(); 3232 CU_ASSERT(g_bserrno == -ENOMEM); 3233 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 3234 3235 /* 3236 * Set cluster size to lower than page size, 3237 * to work it is required to be at least twice the blobstore page size. 3238 */ 3239 dev = init_dev(); 3240 spdk_bs_opts_init(&opts, sizeof(opts)); 3241 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 3242 3243 /* Initialize a new blob store */ 3244 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3245 poll_threads(); 3246 CU_ASSERT(g_bserrno == -EINVAL); 3247 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 3248 3249 /* Set cluster size to twice the default */ 3250 dev = init_dev(); 3251 spdk_bs_opts_init(&opts, sizeof(opts)); 3252 opts.cluster_sz *= 2; 3253 cluster_sz = opts.cluster_sz; 3254 3255 /* Initialize a new blob store */ 3256 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3257 poll_threads(); 3258 CU_ASSERT(g_bserrno == 0); 3259 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3260 bs = g_bs; 3261 3262 CU_ASSERT(spdk_bs_get_cluster_size(bs) == cluster_sz); 3263 3264 ut_bs_reload(&bs, &opts); 3265 3266 CU_ASSERT(spdk_bs_get_cluster_size(bs) == cluster_sz); 3267 3268 spdk_bs_unload(bs, bs_op_complete, NULL); 3269 poll_threads(); 3270 CU_ASSERT(g_bserrno == 0); 3271 g_bs = NULL; 3272 } 3273 3274 /* 3275 * Create a blobstore, reload it and ensure total usable cluster count 3276 * stays the same. 3277 */ 3278 static void 3279 bs_usable_clusters(void) 3280 { 3281 struct spdk_blob_store *bs = g_bs; 3282 struct spdk_blob *blob; 3283 uint32_t clusters; 3284 int i; 3285 3286 3287 clusters = spdk_bs_total_data_cluster_count(bs); 3288 3289 ut_bs_reload(&bs, NULL); 3290 3291 CU_ASSERT(spdk_bs_total_data_cluster_count(bs) == clusters); 3292 3293 /* Create and resize blobs to make sure that useable cluster count won't change */ 3294 for (i = 0; i < 4; i++) { 3295 g_bserrno = -1; 3296 g_blobid = SPDK_BLOBID_INVALID; 3297 blob = ut_blob_create_and_open(bs, NULL); 3298 3299 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3300 poll_threads(); 3301 CU_ASSERT(g_bserrno == 0); 3302 3303 g_bserrno = -1; 3304 spdk_blob_close(blob, blob_op_complete, NULL); 3305 poll_threads(); 3306 CU_ASSERT(g_bserrno == 0); 3307 3308 CU_ASSERT(spdk_bs_total_data_cluster_count(bs) == clusters); 3309 } 3310 3311 /* Reload the blob store to make sure that nothing changed */ 3312 ut_bs_reload(&bs, NULL); 3313 3314 CU_ASSERT(spdk_bs_total_data_cluster_count(bs) == clusters); 3315 } 3316 3317 /* 3318 * Test resizing of the metadata blob. This requires creating enough blobs 3319 * so that one cluster is not enough to fit the metadata for those blobs. 3320 * To induce this condition to happen more quickly, we reduce the cluster 3321 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 3322 */ 3323 static void 3324 bs_resize_md(void) 3325 { 3326 struct spdk_blob_store *bs; 3327 const int CLUSTER_PAGE_COUNT = 4; 3328 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 3329 struct spdk_bs_dev *dev; 3330 struct spdk_bs_opts opts; 3331 struct spdk_blob *blob; 3332 struct spdk_blob_opts blob_opts; 3333 uint32_t cluster_sz; 3334 spdk_blob_id blobids[NUM_BLOBS]; 3335 int i; 3336 3337 3338 dev = init_dev(); 3339 spdk_bs_opts_init(&opts, sizeof(opts)); 3340 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 3341 cluster_sz = opts.cluster_sz; 3342 3343 /* Initialize a new blob store */ 3344 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3345 poll_threads(); 3346 CU_ASSERT(g_bserrno == 0); 3347 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3348 bs = g_bs; 3349 3350 CU_ASSERT(spdk_bs_get_cluster_size(bs) == cluster_sz); 3351 3352 ut_spdk_blob_opts_init(&blob_opts); 3353 3354 for (i = 0; i < NUM_BLOBS; i++) { 3355 g_bserrno = -1; 3356 g_blobid = SPDK_BLOBID_INVALID; 3357 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3358 poll_threads(); 3359 CU_ASSERT(g_bserrno == 0); 3360 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3361 blobids[i] = g_blobid; 3362 } 3363 3364 ut_bs_reload(&bs, &opts); 3365 3366 CU_ASSERT(spdk_bs_get_cluster_size(bs) == cluster_sz); 3367 3368 for (i = 0; i < NUM_BLOBS; i++) { 3369 g_bserrno = -1; 3370 g_blob = NULL; 3371 spdk_bs_open_blob(bs, blobids[i], blob_op_with_handle_complete, NULL); 3372 poll_threads(); 3373 CU_ASSERT(g_bserrno == 0); 3374 CU_ASSERT(g_blob != NULL); 3375 blob = g_blob; 3376 g_bserrno = -1; 3377 spdk_blob_close(blob, blob_op_complete, NULL); 3378 poll_threads(); 3379 CU_ASSERT(g_bserrno == 0); 3380 } 3381 3382 spdk_bs_unload(bs, bs_op_complete, NULL); 3383 poll_threads(); 3384 CU_ASSERT(g_bserrno == 0); 3385 g_bs = NULL; 3386 } 3387 3388 static void 3389 bs_destroy(void) 3390 { 3391 struct spdk_blob_store *bs; 3392 struct spdk_bs_dev *dev; 3393 3394 /* Initialize a new blob store */ 3395 dev = init_dev(); 3396 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3397 poll_threads(); 3398 CU_ASSERT(g_bserrno == 0); 3399 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3400 bs = g_bs; 3401 3402 /* Destroy the blob store */ 3403 g_bserrno = -1; 3404 spdk_bs_destroy(bs, bs_op_complete, NULL); 3405 poll_threads(); 3406 CU_ASSERT(g_bserrno == 0); 3407 3408 /* Loading an non-existent blob store should fail. */ 3409 g_bs = NULL; 3410 dev = init_dev(); 3411 3412 g_bserrno = 0; 3413 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3414 poll_threads(); 3415 CU_ASSERT(g_bserrno != 0); 3416 } 3417 3418 /* Try to hit all of the corner cases associated with serializing 3419 * a blob to disk 3420 */ 3421 static void 3422 blob_serialize_test(void) 3423 { 3424 struct spdk_bs_dev *dev; 3425 struct spdk_bs_opts opts; 3426 struct spdk_blob_store *bs; 3427 spdk_blob_id blobid[2]; 3428 struct spdk_blob *blob[2]; 3429 uint64_t i; 3430 char *value; 3431 int rc; 3432 3433 dev = init_dev(); 3434 3435 /* Initialize a new blobstore with very small clusters */ 3436 spdk_bs_opts_init(&opts, sizeof(opts)); 3437 opts.cluster_sz = dev->blocklen * 8; 3438 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3439 poll_threads(); 3440 CU_ASSERT(g_bserrno == 0); 3441 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3442 bs = g_bs; 3443 3444 /* Create and open two blobs */ 3445 for (i = 0; i < 2; i++) { 3446 blob[i] = ut_blob_create_and_open(bs, NULL); 3447 blobid[i] = spdk_blob_get_id(blob[i]); 3448 3449 /* Set a fairly large xattr on both blobs to eat up 3450 * metadata space 3451 */ 3452 value = calloc(dev->blocklen - 64, sizeof(char)); 3453 SPDK_CU_ASSERT_FATAL(value != NULL); 3454 memset(value, i, dev->blocklen / 2); 3455 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 3456 CU_ASSERT(rc == 0); 3457 free(value); 3458 } 3459 3460 /* Resize the blobs, alternating 1 cluster at a time. 3461 * This thwarts run length encoding and will cause spill 3462 * over of the extents. 3463 */ 3464 for (i = 0; i < 6; i++) { 3465 spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL); 3466 poll_threads(); 3467 CU_ASSERT(g_bserrno == 0); 3468 } 3469 3470 for (i = 0; i < 2; i++) { 3471 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 3472 poll_threads(); 3473 CU_ASSERT(g_bserrno == 0); 3474 } 3475 3476 /* Close the blobs */ 3477 for (i = 0; i < 2; i++) { 3478 spdk_blob_close(blob[i], blob_op_complete, NULL); 3479 poll_threads(); 3480 CU_ASSERT(g_bserrno == 0); 3481 } 3482 3483 ut_bs_reload(&bs, &opts); 3484 3485 for (i = 0; i < 2; i++) { 3486 blob[i] = NULL; 3487 3488 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 3489 poll_threads(); 3490 CU_ASSERT(g_bserrno == 0); 3491 CU_ASSERT(g_blob != NULL); 3492 blob[i] = g_blob; 3493 3494 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 3495 3496 spdk_blob_close(blob[i], blob_op_complete, NULL); 3497 poll_threads(); 3498 CU_ASSERT(g_bserrno == 0); 3499 } 3500 3501 spdk_bs_unload(bs, bs_op_complete, NULL); 3502 poll_threads(); 3503 CU_ASSERT(g_bserrno == 0); 3504 g_bs = NULL; 3505 } 3506 3507 static void 3508 blob_crc(void) 3509 { 3510 struct spdk_blob_store *bs = g_bs; 3511 struct spdk_blob *blob; 3512 spdk_blob_id blobid; 3513 uint32_t page_num; 3514 int index; 3515 struct spdk_blob_md_page *page; 3516 3517 blob = ut_blob_create_and_open(bs, NULL); 3518 blobid = spdk_blob_get_id(blob); 3519 3520 spdk_blob_close(blob, blob_op_complete, NULL); 3521 poll_threads(); 3522 CU_ASSERT(g_bserrno == 0); 3523 3524 page_num = bs_blobid_to_page(blobid); 3525 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 3526 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3527 page->crc = 0; 3528 3529 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3530 poll_threads(); 3531 CU_ASSERT(g_bserrno == -EINVAL); 3532 CU_ASSERT(g_blob == NULL); 3533 g_bserrno = 0; 3534 3535 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3536 poll_threads(); 3537 CU_ASSERT(g_bserrno == -EINVAL); 3538 } 3539 3540 static void 3541 super_block_crc(void) 3542 { 3543 struct spdk_blob_store *bs; 3544 struct spdk_bs_dev *dev; 3545 struct spdk_bs_super_block *super_block; 3546 3547 dev = init_dev(); 3548 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3549 poll_threads(); 3550 CU_ASSERT(g_bserrno == 0); 3551 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3552 bs = g_bs; 3553 3554 spdk_bs_unload(bs, bs_op_complete, NULL); 3555 poll_threads(); 3556 CU_ASSERT(g_bserrno == 0); 3557 g_bs = NULL; 3558 3559 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 3560 super_block->crc = 0; 3561 dev = init_dev(); 3562 3563 /* Load an existing blob store */ 3564 g_bserrno = 0; 3565 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3566 poll_threads(); 3567 CU_ASSERT(g_bserrno == -EILSEQ); 3568 } 3569 3570 /* For blob dirty shutdown test case we do the following sub-test cases: 3571 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we 3572 * dirty shutdown and reload the blob store and verify the xattrs. 3573 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 3574 * reload the blob store and verify the clusters number. 3575 * 3 Create the second blob and then dirty shutdown, reload the blob store 3576 * and verify the second blob. 3577 * 4 Delete the second blob and then dirty shutdown, reload the blob store 3578 * and verify the second blob is invalid. 3579 * 5 Create the second blob again and also create the third blob, modify the 3580 * md of second blob which makes the md invalid, and then dirty shutdown, 3581 * reload the blob store verify the second blob, it should invalid and also 3582 * verify the third blob, it should correct. 3583 */ 3584 static void 3585 blob_dirty_shutdown(void) 3586 { 3587 int rc; 3588 int index; 3589 struct spdk_blob_store *bs = g_bs; 3590 spdk_blob_id blobid1, blobid2, blobid3; 3591 struct spdk_blob *blob = g_blob; 3592 uint64_t length; 3593 uint64_t free_clusters; 3594 const void *value; 3595 size_t value_len; 3596 uint32_t page_num; 3597 struct spdk_blob_md_page *page; 3598 struct spdk_blob_opts blob_opts; 3599 3600 /* Create first blob */ 3601 blobid1 = spdk_blob_get_id(blob); 3602 3603 /* Set some xattrs */ 3604 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 3605 CU_ASSERT(rc == 0); 3606 3607 length = 2345; 3608 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3609 CU_ASSERT(rc == 0); 3610 3611 /* Put xattr that fits exactly single page. 3612 * This results in adding additional pages to MD. 3613 * First is flags and smaller xattr, second the large xattr, 3614 * third are just the extents. 3615 */ 3616 size_t xattr_length = 4072 - sizeof(struct spdk_blob_md_descriptor_xattr) - 3617 strlen("large_xattr"); 3618 char *xattr = calloc(xattr_length, sizeof(char)); 3619 SPDK_CU_ASSERT_FATAL(xattr != NULL); 3620 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); 3621 free(xattr); 3622 SPDK_CU_ASSERT_FATAL(rc == 0); 3623 3624 /* Resize the blob */ 3625 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3626 poll_threads(); 3627 CU_ASSERT(g_bserrno == 0); 3628 3629 /* Set the blob as the super blob */ 3630 spdk_bs_set_super(bs, blobid1, blob_op_complete, NULL); 3631 poll_threads(); 3632 CU_ASSERT(g_bserrno == 0); 3633 3634 free_clusters = spdk_bs_free_cluster_count(bs); 3635 3636 spdk_blob_close(blob, blob_op_complete, NULL); 3637 poll_threads(); 3638 CU_ASSERT(g_bserrno == 0); 3639 blob = NULL; 3640 g_blob = NULL; 3641 g_blobid = SPDK_BLOBID_INVALID; 3642 3643 ut_bs_dirty_load(&bs, NULL); 3644 3645 /* Get the super blob */ 3646 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 3647 poll_threads(); 3648 CU_ASSERT(g_bserrno == 0); 3649 CU_ASSERT(blobid1 == g_blobid); 3650 3651 spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL); 3652 poll_threads(); 3653 CU_ASSERT(g_bserrno == 0); 3654 CU_ASSERT(g_blob != NULL); 3655 blob = g_blob; 3656 3657 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3658 3659 /* Get the xattrs */ 3660 value = NULL; 3661 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3662 CU_ASSERT(rc == 0); 3663 SPDK_CU_ASSERT_FATAL(value != NULL); 3664 CU_ASSERT(*(uint64_t *)value == length); 3665 CU_ASSERT(value_len == 8); 3666 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3667 3668 /* Resize the blob */ 3669 spdk_blob_resize(blob, 20, blob_op_complete, NULL); 3670 poll_threads(); 3671 CU_ASSERT(g_bserrno == 0); 3672 3673 free_clusters = spdk_bs_free_cluster_count(bs); 3674 3675 spdk_blob_close(blob, blob_op_complete, NULL); 3676 poll_threads(); 3677 CU_ASSERT(g_bserrno == 0); 3678 blob = NULL; 3679 g_blob = NULL; 3680 g_blobid = SPDK_BLOBID_INVALID; 3681 3682 ut_bs_dirty_load(&bs, NULL); 3683 3684 spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL); 3685 poll_threads(); 3686 CU_ASSERT(g_bserrno == 0); 3687 CU_ASSERT(g_blob != NULL); 3688 blob = g_blob; 3689 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 3690 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3691 3692 spdk_blob_close(blob, blob_op_complete, NULL); 3693 poll_threads(); 3694 CU_ASSERT(g_bserrno == 0); 3695 blob = NULL; 3696 g_blob = NULL; 3697 g_blobid = SPDK_BLOBID_INVALID; 3698 3699 /* Create second blob */ 3700 blob = ut_blob_create_and_open(bs, NULL); 3701 blobid2 = spdk_blob_get_id(blob); 3702 3703 /* Set some xattrs */ 3704 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3705 CU_ASSERT(rc == 0); 3706 3707 length = 5432; 3708 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3709 CU_ASSERT(rc == 0); 3710 3711 /* Resize the blob */ 3712 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 3713 poll_threads(); 3714 CU_ASSERT(g_bserrno == 0); 3715 3716 free_clusters = spdk_bs_free_cluster_count(bs); 3717 3718 spdk_blob_close(blob, blob_op_complete, NULL); 3719 poll_threads(); 3720 CU_ASSERT(g_bserrno == 0); 3721 blob = NULL; 3722 g_blob = NULL; 3723 g_blobid = SPDK_BLOBID_INVALID; 3724 3725 ut_bs_dirty_load(&bs, NULL); 3726 3727 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 3728 poll_threads(); 3729 CU_ASSERT(g_bserrno == 0); 3730 CU_ASSERT(g_blob != NULL); 3731 blob = g_blob; 3732 3733 /* Get the xattrs */ 3734 value = NULL; 3735 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 3736 CU_ASSERT(rc == 0); 3737 SPDK_CU_ASSERT_FATAL(value != NULL); 3738 CU_ASSERT(*(uint64_t *)value == length); 3739 CU_ASSERT(value_len == 8); 3740 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 3741 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3742 3743 ut_blob_close_and_delete(bs, blob); 3744 3745 free_clusters = spdk_bs_free_cluster_count(bs); 3746 3747 ut_bs_dirty_load(&bs, NULL); 3748 3749 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 3750 poll_threads(); 3751 CU_ASSERT(g_bserrno != 0); 3752 CU_ASSERT(g_blob == NULL); 3753 3754 spdk_bs_open_blob(bs, blobid1, blob_op_with_handle_complete, NULL); 3755 poll_threads(); 3756 CU_ASSERT(g_bserrno == 0); 3757 CU_ASSERT(g_blob != NULL); 3758 blob = g_blob; 3759 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3760 spdk_blob_close(blob, blob_op_complete, NULL); 3761 poll_threads(); 3762 CU_ASSERT(g_bserrno == 0); 3763 3764 ut_bs_reload(&bs, NULL); 3765 3766 /* Create second blob */ 3767 ut_spdk_blob_opts_init(&blob_opts); 3768 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3769 poll_threads(); 3770 CU_ASSERT(g_bserrno == 0); 3771 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3772 blobid2 = g_blobid; 3773 3774 /* Create third blob */ 3775 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 3776 poll_threads(); 3777 CU_ASSERT(g_bserrno == 0); 3778 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3779 blobid3 = g_blobid; 3780 3781 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 3782 poll_threads(); 3783 CU_ASSERT(g_bserrno == 0); 3784 CU_ASSERT(g_blob != NULL); 3785 blob = g_blob; 3786 3787 /* Set some xattrs for second blob */ 3788 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 3789 CU_ASSERT(rc == 0); 3790 3791 length = 5432; 3792 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3793 CU_ASSERT(rc == 0); 3794 3795 spdk_blob_close(blob, blob_op_complete, NULL); 3796 poll_threads(); 3797 CU_ASSERT(g_bserrno == 0); 3798 blob = NULL; 3799 g_blob = NULL; 3800 g_blobid = SPDK_BLOBID_INVALID; 3801 3802 spdk_bs_open_blob(bs, blobid3, blob_op_with_handle_complete, NULL); 3803 poll_threads(); 3804 CU_ASSERT(g_bserrno == 0); 3805 CU_ASSERT(g_blob != NULL); 3806 blob = g_blob; 3807 3808 /* Set some xattrs for third blob */ 3809 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 3810 CU_ASSERT(rc == 0); 3811 3812 length = 5432; 3813 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 3814 CU_ASSERT(rc == 0); 3815 3816 spdk_blob_close(blob, blob_op_complete, NULL); 3817 poll_threads(); 3818 CU_ASSERT(g_bserrno == 0); 3819 blob = NULL; 3820 g_blob = NULL; 3821 g_blobid = SPDK_BLOBID_INVALID; 3822 3823 /* Mark second blob as invalid */ 3824 page_num = bs_blobid_to_page(blobid2); 3825 3826 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 3827 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 3828 page->sequence_num = 1; 3829 page->crc = blob_md_page_calc_crc(page); 3830 3831 free_clusters = spdk_bs_free_cluster_count(bs); 3832 3833 ut_bs_dirty_load(&bs, NULL); 3834 3835 spdk_bs_open_blob(bs, blobid2, blob_op_with_handle_complete, NULL); 3836 poll_threads(); 3837 CU_ASSERT(g_bserrno != 0); 3838 CU_ASSERT(g_blob == NULL); 3839 3840 spdk_bs_open_blob(bs, blobid3, blob_op_with_handle_complete, NULL); 3841 poll_threads(); 3842 CU_ASSERT(g_bserrno == 0); 3843 CU_ASSERT(g_blob != NULL); 3844 blob = g_blob; 3845 3846 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3847 } 3848 3849 static void 3850 blob_flags(void) 3851 { 3852 struct spdk_blob_store *bs = g_bs; 3853 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 3854 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 3855 struct spdk_blob_opts blob_opts; 3856 int rc; 3857 3858 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 3859 blob_invalid = ut_blob_create_and_open(bs, NULL); 3860 blobid_invalid = spdk_blob_get_id(blob_invalid); 3861 3862 blob_data_ro = ut_blob_create_and_open(bs, NULL); 3863 blobid_data_ro = spdk_blob_get_id(blob_data_ro); 3864 3865 ut_spdk_blob_opts_init(&blob_opts); 3866 blob_opts.clear_method = BLOB_CLEAR_WITH_WRITE_ZEROES; 3867 blob_md_ro = ut_blob_create_and_open(bs, &blob_opts); 3868 blobid_md_ro = spdk_blob_get_id(blob_md_ro); 3869 CU_ASSERT((blob_md_ro->md_ro_flags & SPDK_BLOB_MD_RO_FLAGS_MASK) == BLOB_CLEAR_WITH_WRITE_ZEROES); 3870 3871 /* Change the size of blob_data_ro to check if flags are serialized 3872 * when blob has non zero number of extents */ 3873 spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL); 3874 poll_threads(); 3875 CU_ASSERT(g_bserrno == 0); 3876 3877 /* Set the xattr to check if flags are serialized 3878 * when blob has non zero number of xattrs */ 3879 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 3880 CU_ASSERT(rc == 0); 3881 3882 blob_invalid->invalid_flags = (1ULL << 63); 3883 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 3884 blob_data_ro->data_ro_flags = (1ULL << 62); 3885 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 3886 blob_md_ro->md_ro_flags = (1ULL << 61); 3887 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 3888 3889 g_bserrno = -1; 3890 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 3891 poll_threads(); 3892 CU_ASSERT(g_bserrno == 0); 3893 g_bserrno = -1; 3894 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 3895 poll_threads(); 3896 CU_ASSERT(g_bserrno == 0); 3897 g_bserrno = -1; 3898 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 3899 poll_threads(); 3900 CU_ASSERT(g_bserrno == 0); 3901 3902 g_bserrno = -1; 3903 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 3904 poll_threads(); 3905 CU_ASSERT(g_bserrno == 0); 3906 blob_invalid = NULL; 3907 g_bserrno = -1; 3908 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 3909 poll_threads(); 3910 CU_ASSERT(g_bserrno == 0); 3911 blob_data_ro = NULL; 3912 g_bserrno = -1; 3913 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 3914 poll_threads(); 3915 CU_ASSERT(g_bserrno == 0); 3916 blob_md_ro = NULL; 3917 3918 g_blob = NULL; 3919 g_blobid = SPDK_BLOBID_INVALID; 3920 3921 ut_bs_reload(&bs, NULL); 3922 3923 g_blob = NULL; 3924 g_bserrno = 0; 3925 spdk_bs_open_blob(bs, blobid_invalid, blob_op_with_handle_complete, NULL); 3926 poll_threads(); 3927 CU_ASSERT(g_bserrno != 0); 3928 CU_ASSERT(g_blob == NULL); 3929 3930 g_blob = NULL; 3931 g_bserrno = -1; 3932 spdk_bs_open_blob(bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 3933 poll_threads(); 3934 CU_ASSERT(g_bserrno == 0); 3935 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3936 blob_data_ro = g_blob; 3937 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 3938 CU_ASSERT(blob_data_ro->data_ro == true); 3939 CU_ASSERT(blob_data_ro->md_ro == true); 3940 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 3941 3942 g_blob = NULL; 3943 g_bserrno = -1; 3944 spdk_bs_open_blob(bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 3945 poll_threads(); 3946 CU_ASSERT(g_bserrno == 0); 3947 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3948 blob_md_ro = g_blob; 3949 CU_ASSERT(blob_md_ro->data_ro == false); 3950 CU_ASSERT(blob_md_ro->md_ro == true); 3951 3952 g_bserrno = -1; 3953 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 3954 poll_threads(); 3955 CU_ASSERT(g_bserrno == 0); 3956 3957 ut_blob_close_and_delete(bs, blob_data_ro); 3958 ut_blob_close_and_delete(bs, blob_md_ro); 3959 } 3960 3961 static void 3962 bs_version(void) 3963 { 3964 struct spdk_bs_super_block *super; 3965 struct spdk_blob_store *bs = g_bs; 3966 struct spdk_bs_dev *dev; 3967 struct spdk_blob *blob; 3968 struct spdk_blob_opts blob_opts; 3969 spdk_blob_id blobid; 3970 3971 /* Unload the blob store */ 3972 spdk_bs_unload(bs, bs_op_complete, NULL); 3973 poll_threads(); 3974 CU_ASSERT(g_bserrno == 0); 3975 g_bs = NULL; 3976 3977 /* 3978 * Change the bs version on disk. This will allow us to 3979 * test that the version does not get modified automatically 3980 * when loading and unloading the blobstore. 3981 */ 3982 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 3983 CU_ASSERT(super->version == SPDK_BS_VERSION); 3984 CU_ASSERT(super->clean == 1); 3985 super->version = 2; 3986 /* 3987 * Version 2 metadata does not have a used blobid mask, so clear 3988 * those fields in the super block and zero the corresponding 3989 * region on "disk". We will use this to ensure blob IDs are 3990 * correctly reconstructed. 3991 */ 3992 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 3993 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 3994 super->used_blobid_mask_start = 0; 3995 super->used_blobid_mask_len = 0; 3996 super->crc = blob_md_page_calc_crc(super); 3997 3998 /* Load an existing blob store */ 3999 dev = init_dev(); 4000 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4001 poll_threads(); 4002 CU_ASSERT(g_bserrno == 0); 4003 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4004 CU_ASSERT(super->clean == 1); 4005 bs = g_bs; 4006 4007 /* 4008 * Create a blob - just to make sure that when we unload it 4009 * results in writing the super block (since metadata pages 4010 * were allocated. 4011 */ 4012 ut_spdk_blob_opts_init(&blob_opts); 4013 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 4014 poll_threads(); 4015 CU_ASSERT(g_bserrno == 0); 4016 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4017 blobid = g_blobid; 4018 4019 /* Unload the blob store */ 4020 spdk_bs_unload(bs, bs_op_complete, NULL); 4021 poll_threads(); 4022 CU_ASSERT(g_bserrno == 0); 4023 g_bs = NULL; 4024 CU_ASSERT(super->version == 2); 4025 CU_ASSERT(super->used_blobid_mask_start == 0); 4026 CU_ASSERT(super->used_blobid_mask_len == 0); 4027 4028 dev = init_dev(); 4029 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4030 poll_threads(); 4031 CU_ASSERT(g_bserrno == 0); 4032 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4033 bs = g_bs; 4034 4035 g_blob = NULL; 4036 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4037 poll_threads(); 4038 CU_ASSERT(g_bserrno == 0); 4039 CU_ASSERT(g_blob != NULL); 4040 blob = g_blob; 4041 4042 ut_blob_close_and_delete(bs, blob); 4043 4044 CU_ASSERT(super->version == 2); 4045 CU_ASSERT(super->used_blobid_mask_start == 0); 4046 CU_ASSERT(super->used_blobid_mask_len == 0); 4047 } 4048 4049 static void 4050 blob_set_xattrs_test(void) 4051 { 4052 struct spdk_blob_store *bs = g_bs; 4053 struct spdk_blob *blob; 4054 struct spdk_blob_opts opts; 4055 const void *value; 4056 size_t value_len; 4057 char *xattr; 4058 size_t xattr_length; 4059 int rc; 4060 4061 /* Create blob with extra attributes */ 4062 ut_spdk_blob_opts_init(&opts); 4063 4064 opts.xattrs.names = g_xattr_names; 4065 opts.xattrs.get_value = _get_xattr_value; 4066 opts.xattrs.count = 3; 4067 opts.xattrs.ctx = &g_ctx; 4068 4069 blob = ut_blob_create_and_open(bs, &opts); 4070 4071 /* Get the xattrs */ 4072 value = NULL; 4073 4074 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 4075 CU_ASSERT(rc == 0); 4076 SPDK_CU_ASSERT_FATAL(value != NULL); 4077 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 4078 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 4079 4080 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 4081 CU_ASSERT(rc == 0); 4082 SPDK_CU_ASSERT_FATAL(value != NULL); 4083 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 4084 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 4085 4086 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 4087 CU_ASSERT(rc == 0); 4088 SPDK_CU_ASSERT_FATAL(value != NULL); 4089 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 4090 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 4091 4092 /* Try to get non existing attribute */ 4093 4094 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 4095 CU_ASSERT(rc == -ENOENT); 4096 4097 /* Try xattr exceeding maximum length of descriptor in single page */ 4098 xattr_length = SPDK_BS_MAX_DESC_SIZE - sizeof(struct spdk_blob_md_descriptor_xattr) - 4099 strlen("large_xattr") + 1; 4100 xattr = calloc(xattr_length, sizeof(char)); 4101 SPDK_CU_ASSERT_FATAL(xattr != NULL); 4102 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); 4103 free(xattr); 4104 SPDK_CU_ASSERT_FATAL(rc == -ENOMEM); 4105 4106 spdk_blob_close(blob, blob_op_complete, NULL); 4107 poll_threads(); 4108 CU_ASSERT(g_bserrno == 0); 4109 blob = NULL; 4110 g_blob = NULL; 4111 g_blobid = SPDK_BLOBID_INVALID; 4112 4113 /* NULL callback */ 4114 ut_spdk_blob_opts_init(&opts); 4115 opts.xattrs.names = g_xattr_names; 4116 opts.xattrs.get_value = NULL; 4117 opts.xattrs.count = 1; 4118 opts.xattrs.ctx = &g_ctx; 4119 4120 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4121 poll_threads(); 4122 CU_ASSERT(g_bserrno == -EINVAL); 4123 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4124 4125 /* NULL values */ 4126 ut_spdk_blob_opts_init(&opts); 4127 opts.xattrs.names = g_xattr_names; 4128 opts.xattrs.get_value = _get_xattr_value_null; 4129 opts.xattrs.count = 1; 4130 opts.xattrs.ctx = NULL; 4131 4132 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4133 poll_threads(); 4134 CU_ASSERT(g_bserrno == -EINVAL); 4135 } 4136 4137 static void 4138 blob_thin_prov_alloc(void) 4139 { 4140 struct spdk_blob_store *bs = g_bs; 4141 struct spdk_blob *blob; 4142 struct spdk_blob_opts opts; 4143 spdk_blob_id blobid; 4144 uint64_t free_clusters; 4145 4146 free_clusters = spdk_bs_free_cluster_count(bs); 4147 4148 /* Set blob as thin provisioned */ 4149 ut_spdk_blob_opts_init(&opts); 4150 opts.thin_provision = true; 4151 4152 blob = ut_blob_create_and_open(bs, &opts); 4153 blobid = spdk_blob_get_id(blob); 4154 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4155 4156 CU_ASSERT(blob->active.num_clusters == 0); 4157 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 4158 4159 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4160 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4161 poll_threads(); 4162 CU_ASSERT(g_bserrno == 0); 4163 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4164 CU_ASSERT(blob->active.num_clusters == 5); 4165 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4166 4167 /* Grow it to 1TB - still unallocated */ 4168 spdk_blob_resize(blob, 262144, blob_op_complete, NULL); 4169 poll_threads(); 4170 CU_ASSERT(g_bserrno == 0); 4171 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4172 CU_ASSERT(blob->active.num_clusters == 262144); 4173 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 4174 4175 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4176 poll_threads(); 4177 CU_ASSERT(g_bserrno == 0); 4178 /* Sync must not change anything */ 4179 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4180 CU_ASSERT(blob->active.num_clusters == 262144); 4181 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 262144); 4182 /* Since clusters are not allocated, 4183 * number of metadata pages is expected to be minimal. 4184 */ 4185 CU_ASSERT(blob->active.num_pages == 1); 4186 4187 /* Shrink the blob to 3 clusters - still unallocated */ 4188 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 4189 poll_threads(); 4190 CU_ASSERT(g_bserrno == 0); 4191 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4192 CU_ASSERT(blob->active.num_clusters == 3); 4193 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 4194 4195 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4196 poll_threads(); 4197 CU_ASSERT(g_bserrno == 0); 4198 /* Sync must not change anything */ 4199 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4200 CU_ASSERT(blob->active.num_clusters == 3); 4201 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 4202 4203 spdk_blob_close(blob, blob_op_complete, NULL); 4204 poll_threads(); 4205 CU_ASSERT(g_bserrno == 0); 4206 4207 ut_bs_reload(&bs, NULL); 4208 4209 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4210 poll_threads(); 4211 CU_ASSERT(g_bserrno == 0); 4212 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4213 blob = g_blob; 4214 4215 /* Check that clusters allocation and size is still the same */ 4216 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4217 CU_ASSERT(blob->active.num_clusters == 3); 4218 4219 ut_blob_close_and_delete(bs, blob); 4220 } 4221 4222 static void 4223 blob_insert_cluster_msg_test(void) 4224 { 4225 struct spdk_blob_store *bs = g_bs; 4226 struct spdk_blob *blob; 4227 struct spdk_blob_opts opts; 4228 struct spdk_blob_md_page page = {}; 4229 spdk_blob_id blobid; 4230 uint64_t free_clusters; 4231 uint64_t new_cluster = 0; 4232 uint32_t cluster_num = 3; 4233 uint32_t extent_page = 0; 4234 4235 free_clusters = spdk_bs_free_cluster_count(bs); 4236 4237 /* Set blob as thin provisioned */ 4238 ut_spdk_blob_opts_init(&opts); 4239 opts.thin_provision = true; 4240 opts.num_clusters = 4; 4241 4242 blob = ut_blob_create_and_open(bs, &opts); 4243 blobid = spdk_blob_get_id(blob); 4244 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4245 4246 CU_ASSERT(blob->active.num_clusters == 4); 4247 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 4248 CU_ASSERT(blob->active.clusters[cluster_num] == 0); 4249 4250 /* Specify cluster_num to allocate and new_cluster will be returned to insert on md_thread. 4251 * This is to simulate behaviour when cluster is allocated after blob creation. 4252 * Such as _spdk_bs_allocate_and_copy_cluster(). */ 4253 spdk_spin_lock(&bs->used_lock); 4254 bs_allocate_cluster(blob, cluster_num, &new_cluster, &extent_page, false); 4255 CU_ASSERT(blob->active.clusters[cluster_num] == 0); 4256 spdk_spin_unlock(&bs->used_lock); 4257 4258 blob_insert_cluster_on_md_thread(blob, cluster_num, new_cluster, extent_page, &page, 4259 blob_op_complete, NULL); 4260 poll_threads(); 4261 4262 CU_ASSERT(blob->active.clusters[cluster_num] != 0); 4263 4264 spdk_blob_close(blob, blob_op_complete, NULL); 4265 poll_threads(); 4266 CU_ASSERT(g_bserrno == 0); 4267 4268 ut_bs_reload(&bs, NULL); 4269 4270 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4271 poll_threads(); 4272 CU_ASSERT(g_bserrno == 0); 4273 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4274 blob = g_blob; 4275 4276 CU_ASSERT(blob->active.clusters[cluster_num] != 0); 4277 4278 ut_blob_close_and_delete(bs, blob); 4279 } 4280 4281 static void 4282 blob_thin_prov_rw(void) 4283 { 4284 static const uint8_t zero[10 * 4096] = { 0 }; 4285 struct spdk_blob_store *bs = g_bs; 4286 struct spdk_blob *blob, *blob_id0; 4287 struct spdk_io_channel *channel, *channel_thread1; 4288 struct spdk_blob_opts opts; 4289 uint64_t free_clusters; 4290 uint64_t page_size; 4291 uint8_t payload_read[10 * 4096]; 4292 uint8_t payload_write[10 * 4096]; 4293 uint64_t write_bytes; 4294 uint64_t read_bytes; 4295 4296 free_clusters = spdk_bs_free_cluster_count(bs); 4297 page_size = spdk_bs_get_page_size(bs); 4298 4299 channel = spdk_bs_alloc_io_channel(bs); 4300 CU_ASSERT(channel != NULL); 4301 4302 ut_spdk_blob_opts_init(&opts); 4303 opts.thin_provision = true; 4304 4305 /* Create and delete blob at md page 0, so that next md page allocation 4306 * for extent will use that. */ 4307 blob_id0 = ut_blob_create_and_open(bs, &opts); 4308 blob = ut_blob_create_and_open(bs, &opts); 4309 ut_blob_close_and_delete(bs, blob_id0); 4310 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4311 4312 CU_ASSERT(blob->active.num_clusters == 0); 4313 4314 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4315 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4316 poll_threads(); 4317 CU_ASSERT(g_bserrno == 0); 4318 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4319 CU_ASSERT(blob->active.num_clusters == 5); 4320 4321 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4322 poll_threads(); 4323 CU_ASSERT(g_bserrno == 0); 4324 /* Sync must not change anything */ 4325 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4326 CU_ASSERT(blob->active.num_clusters == 5); 4327 4328 /* Payload should be all zeros from unallocated clusters */ 4329 memset(payload_read, 0xFF, sizeof(payload_read)); 4330 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4331 poll_threads(); 4332 CU_ASSERT(g_bserrno == 0); 4333 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4334 4335 write_bytes = g_dev_write_bytes; 4336 read_bytes = g_dev_read_bytes; 4337 4338 /* Perform write on thread 1. That will allocate cluster on thread 0 via send_msg */ 4339 set_thread(1); 4340 channel_thread1 = spdk_bs_alloc_io_channel(bs); 4341 CU_ASSERT(channel_thread1 != NULL); 4342 memset(payload_write, 0xE5, sizeof(payload_write)); 4343 spdk_blob_io_write(blob, channel_thread1, payload_write, 4, 10, blob_op_complete, NULL); 4344 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4345 /* Perform write on thread 0. That will try to allocate cluster, 4346 * but fail due to another thread issuing the cluster allocation first. */ 4347 set_thread(0); 4348 memset(payload_write, 0xE5, sizeof(payload_write)); 4349 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4350 CU_ASSERT(free_clusters - 2 == spdk_bs_free_cluster_count(bs)); 4351 poll_threads(); 4352 CU_ASSERT(g_bserrno == 0); 4353 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4354 /* For thin-provisioned blob we need to write 20 pages plus one page metadata and 4355 * read 0 bytes */ 4356 if (g_use_extent_table) { 4357 /* Add one more page for EXTENT_PAGE write */ 4358 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 22); 4359 } else { 4360 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 21); 4361 } 4362 CU_ASSERT(g_dev_read_bytes - read_bytes == 0); 4363 4364 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4365 poll_threads(); 4366 CU_ASSERT(g_bserrno == 0); 4367 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4368 4369 ut_blob_close_and_delete(bs, blob); 4370 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4371 4372 set_thread(1); 4373 spdk_bs_free_io_channel(channel_thread1); 4374 set_thread(0); 4375 spdk_bs_free_io_channel(channel); 4376 poll_threads(); 4377 g_blob = NULL; 4378 g_blobid = 0; 4379 } 4380 4381 static void 4382 blob_thin_prov_write_count_io(void) 4383 { 4384 struct spdk_blob_store *bs; 4385 struct spdk_blob *blob; 4386 struct spdk_io_channel *ch; 4387 struct spdk_bs_dev *dev; 4388 struct spdk_bs_opts bs_opts; 4389 struct spdk_blob_opts opts; 4390 uint64_t free_clusters; 4391 uint64_t page_size; 4392 uint8_t payload_write[4096]; 4393 uint64_t write_bytes; 4394 uint64_t read_bytes; 4395 const uint32_t CLUSTER_SZ = 16384; 4396 uint32_t pages_per_cluster; 4397 uint32_t pages_per_extent_page; 4398 uint32_t i; 4399 4400 /* Use a very small cluster size for this test. This ensures we need multiple 4401 * extent pages to hold all of the clusters even for relatively small blobs like 4402 * we are restricted to for the unit tests (i.e. we don't want to allocate multi-GB 4403 * buffers). 4404 */ 4405 dev = init_dev(); 4406 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 4407 bs_opts.cluster_sz = CLUSTER_SZ; 4408 4409 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 4410 poll_threads(); 4411 CU_ASSERT(g_bserrno == 0); 4412 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4413 bs = g_bs; 4414 4415 free_clusters = spdk_bs_free_cluster_count(bs); 4416 page_size = spdk_bs_get_page_size(bs); 4417 pages_per_cluster = CLUSTER_SZ / page_size; 4418 pages_per_extent_page = SPDK_EXTENTS_PER_EP * pages_per_cluster; 4419 4420 ch = spdk_bs_alloc_io_channel(bs); 4421 SPDK_CU_ASSERT_FATAL(ch != NULL); 4422 4423 ut_spdk_blob_opts_init(&opts); 4424 opts.thin_provision = true; 4425 4426 blob = ut_blob_create_and_open(bs, &opts); 4427 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4428 4429 /* Resize the blob so that it will require 8 extent pages to hold all of 4430 * the clusters. 4431 */ 4432 g_bserrno = -1; 4433 spdk_blob_resize(blob, SPDK_EXTENTS_PER_EP * 8, blob_op_complete, NULL); 4434 poll_threads(); 4435 CU_ASSERT(g_bserrno == 0); 4436 4437 g_bserrno = -1; 4438 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4439 poll_threads(); 4440 CU_ASSERT(g_bserrno == 0); 4441 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4442 CU_ASSERT(blob->active.num_clusters == SPDK_EXTENTS_PER_EP * 8); 4443 4444 memset(payload_write, 0, sizeof(payload_write)); 4445 for (i = 0; i < 8; i++) { 4446 write_bytes = g_dev_write_bytes; 4447 read_bytes = g_dev_read_bytes; 4448 4449 g_bserrno = -1; 4450 spdk_blob_io_write(blob, ch, payload_write, pages_per_extent_page * i, 1, blob_op_complete, NULL); 4451 poll_threads(); 4452 CU_ASSERT(g_bserrno == 0); 4453 CU_ASSERT(free_clusters - (2 * i + 1) == spdk_bs_free_cluster_count(bs)); 4454 4455 CU_ASSERT(g_dev_read_bytes == read_bytes); 4456 if (!g_use_extent_table) { 4457 /* For legacy metadata, we should have written two pages - one for the 4458 * write I/O itself, another for the blob's primary metadata. 4459 */ 4460 CU_ASSERT((g_dev_write_bytes - write_bytes) / page_size == 2); 4461 } else { 4462 /* For extent table metadata, we should have written three pages - one 4463 * for the write I/O, one for the extent page, one for the blob's primary 4464 * metadata. 4465 */ 4466 CU_ASSERT((g_dev_write_bytes - write_bytes) / page_size == 3); 4467 } 4468 4469 /* The write should have synced the metadata already. Do another sync here 4470 * just to confirm. 4471 */ 4472 write_bytes = g_dev_write_bytes; 4473 read_bytes = g_dev_read_bytes; 4474 4475 g_bserrno = -1; 4476 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4477 poll_threads(); 4478 CU_ASSERT(g_bserrno == 0); 4479 CU_ASSERT(free_clusters - (2 * i + 1) == spdk_bs_free_cluster_count(bs)); 4480 4481 CU_ASSERT(g_dev_read_bytes == read_bytes); 4482 CU_ASSERT(g_dev_write_bytes == write_bytes); 4483 4484 /* Now write to another unallocated cluster that is part of the same extent page. */ 4485 g_bserrno = -1; 4486 spdk_blob_io_write(blob, ch, payload_write, pages_per_extent_page * i + pages_per_cluster, 4487 1, blob_op_complete, NULL); 4488 poll_threads(); 4489 CU_ASSERT(g_bserrno == 0); 4490 CU_ASSERT(free_clusters - (2 * i + 2) == spdk_bs_free_cluster_count(bs)); 4491 4492 CU_ASSERT(g_dev_read_bytes == read_bytes); 4493 /* 4494 * For legacy metadata, we should have written the I/O and the primary metadata page. 4495 * For extent table metadata, we should have written the I/O and the extent metadata page. 4496 */ 4497 CU_ASSERT((g_dev_write_bytes - write_bytes) / page_size == 2); 4498 } 4499 4500 ut_blob_close_and_delete(bs, blob); 4501 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4502 4503 spdk_bs_free_io_channel(ch); 4504 poll_threads(); 4505 g_blob = NULL; 4506 g_blobid = 0; 4507 4508 spdk_bs_unload(bs, bs_op_complete, NULL); 4509 poll_threads(); 4510 CU_ASSERT(g_bserrno == 0); 4511 g_bs = NULL; 4512 } 4513 4514 static void 4515 blob_thin_prov_rle(void) 4516 { 4517 static const uint8_t zero[10 * 4096] = { 0 }; 4518 struct spdk_blob_store *bs = g_bs; 4519 struct spdk_blob *blob; 4520 struct spdk_io_channel *channel; 4521 struct spdk_blob_opts opts; 4522 spdk_blob_id blobid; 4523 uint64_t free_clusters; 4524 uint64_t page_size; 4525 uint8_t payload_read[10 * 4096]; 4526 uint8_t payload_write[10 * 4096]; 4527 uint64_t write_bytes; 4528 uint64_t read_bytes; 4529 uint64_t io_unit; 4530 4531 free_clusters = spdk_bs_free_cluster_count(bs); 4532 page_size = spdk_bs_get_page_size(bs); 4533 4534 ut_spdk_blob_opts_init(&opts); 4535 opts.thin_provision = true; 4536 opts.num_clusters = 5; 4537 4538 blob = ut_blob_create_and_open(bs, &opts); 4539 blobid = spdk_blob_get_id(blob); 4540 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4541 4542 channel = spdk_bs_alloc_io_channel(bs); 4543 CU_ASSERT(channel != NULL); 4544 4545 /* Target specifically second cluster in a blob as first allocation */ 4546 io_unit = bs_cluster_to_page(bs, 1) * bs_io_unit_per_page(bs); 4547 4548 /* Payload should be all zeros from unallocated clusters */ 4549 memset(payload_read, 0xFF, sizeof(payload_read)); 4550 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL); 4551 poll_threads(); 4552 CU_ASSERT(g_bserrno == 0); 4553 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4554 4555 write_bytes = g_dev_write_bytes; 4556 read_bytes = g_dev_read_bytes; 4557 4558 /* Issue write to second cluster in a blob */ 4559 memset(payload_write, 0xE5, sizeof(payload_write)); 4560 spdk_blob_io_write(blob, channel, payload_write, io_unit, 10, blob_op_complete, NULL); 4561 poll_threads(); 4562 CU_ASSERT(g_bserrno == 0); 4563 CU_ASSERT(free_clusters - 1 == spdk_bs_free_cluster_count(bs)); 4564 /* For thin-provisioned blob we need to write 10 pages plus one page metadata and 4565 * read 0 bytes */ 4566 if (g_use_extent_table) { 4567 /* Add one more page for EXTENT_PAGE write */ 4568 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 12); 4569 } else { 4570 CU_ASSERT(g_dev_write_bytes - write_bytes == page_size * 11); 4571 } 4572 CU_ASSERT(g_dev_read_bytes - read_bytes == 0); 4573 4574 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL); 4575 poll_threads(); 4576 CU_ASSERT(g_bserrno == 0); 4577 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4578 4579 spdk_bs_free_io_channel(channel); 4580 poll_threads(); 4581 4582 spdk_blob_close(blob, blob_op_complete, NULL); 4583 poll_threads(); 4584 CU_ASSERT(g_bserrno == 0); 4585 4586 ut_bs_reload(&bs, NULL); 4587 4588 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4589 poll_threads(); 4590 CU_ASSERT(g_bserrno == 0); 4591 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4592 blob = g_blob; 4593 4594 channel = spdk_bs_alloc_io_channel(bs); 4595 CU_ASSERT(channel != NULL); 4596 4597 /* Read second cluster after blob reload to confirm data written */ 4598 spdk_blob_io_read(blob, channel, payload_read, io_unit, 10, blob_op_complete, NULL); 4599 poll_threads(); 4600 CU_ASSERT(g_bserrno == 0); 4601 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4602 4603 spdk_bs_free_io_channel(channel); 4604 poll_threads(); 4605 4606 ut_blob_close_and_delete(bs, blob); 4607 } 4608 4609 static void 4610 blob_thin_prov_rw_iov(void) 4611 { 4612 static const uint8_t zero[10 * 4096] = { 0 }; 4613 struct spdk_blob_store *bs = g_bs; 4614 struct spdk_blob *blob; 4615 struct spdk_io_channel *channel; 4616 struct spdk_blob_opts opts; 4617 uint64_t free_clusters; 4618 uint8_t payload_read[10 * 4096]; 4619 uint8_t payload_write[10 * 4096]; 4620 struct iovec iov_read[3]; 4621 struct iovec iov_write[3]; 4622 4623 free_clusters = spdk_bs_free_cluster_count(bs); 4624 4625 channel = spdk_bs_alloc_io_channel(bs); 4626 CU_ASSERT(channel != NULL); 4627 4628 ut_spdk_blob_opts_init(&opts); 4629 opts.thin_provision = true; 4630 4631 blob = ut_blob_create_and_open(bs, &opts); 4632 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4633 4634 CU_ASSERT(blob->active.num_clusters == 0); 4635 4636 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 4637 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 4638 poll_threads(); 4639 CU_ASSERT(g_bserrno == 0); 4640 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4641 CU_ASSERT(blob->active.num_clusters == 5); 4642 4643 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4644 poll_threads(); 4645 CU_ASSERT(g_bserrno == 0); 4646 /* Sync must not change anything */ 4647 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4648 CU_ASSERT(blob->active.num_clusters == 5); 4649 4650 /* Payload should be all zeros from unallocated clusters */ 4651 memset(payload_read, 0xAA, sizeof(payload_read)); 4652 iov_read[0].iov_base = payload_read; 4653 iov_read[0].iov_len = 3 * 4096; 4654 iov_read[1].iov_base = payload_read + 3 * 4096; 4655 iov_read[1].iov_len = 4 * 4096; 4656 iov_read[2].iov_base = payload_read + 7 * 4096; 4657 iov_read[2].iov_len = 3 * 4096; 4658 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4659 poll_threads(); 4660 CU_ASSERT(g_bserrno == 0); 4661 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4662 4663 memset(payload_write, 0xE5, sizeof(payload_write)); 4664 iov_write[0].iov_base = payload_write; 4665 iov_write[0].iov_len = 1 * 4096; 4666 iov_write[1].iov_base = payload_write + 1 * 4096; 4667 iov_write[1].iov_len = 5 * 4096; 4668 iov_write[2].iov_base = payload_write + 6 * 4096; 4669 iov_write[2].iov_len = 4 * 4096; 4670 4671 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 4672 poll_threads(); 4673 CU_ASSERT(g_bserrno == 0); 4674 4675 memset(payload_read, 0xAA, sizeof(payload_read)); 4676 iov_read[0].iov_base = payload_read; 4677 iov_read[0].iov_len = 3 * 4096; 4678 iov_read[1].iov_base = payload_read + 3 * 4096; 4679 iov_read[1].iov_len = 4 * 4096; 4680 iov_read[2].iov_base = payload_read + 7 * 4096; 4681 iov_read[2].iov_len = 3 * 4096; 4682 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4683 poll_threads(); 4684 CU_ASSERT(g_bserrno == 0); 4685 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4686 4687 spdk_bs_free_io_channel(channel); 4688 poll_threads(); 4689 4690 ut_blob_close_and_delete(bs, blob); 4691 } 4692 4693 struct iter_ctx { 4694 int current_iter; 4695 spdk_blob_id blobid[4]; 4696 }; 4697 4698 static void 4699 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 4700 { 4701 struct iter_ctx *iter_ctx = arg; 4702 spdk_blob_id blobid; 4703 4704 CU_ASSERT(bserrno == 0); 4705 blobid = spdk_blob_get_id(blob); 4706 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 4707 } 4708 4709 static void 4710 bs_load_iter_test(void) 4711 { 4712 struct spdk_blob_store *bs; 4713 struct spdk_bs_dev *dev; 4714 struct iter_ctx iter_ctx = { 0 }; 4715 struct spdk_blob *blob; 4716 int i, rc; 4717 struct spdk_bs_opts opts; 4718 4719 dev = init_dev(); 4720 spdk_bs_opts_init(&opts, sizeof(opts)); 4721 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4722 4723 /* Initialize a new blob store */ 4724 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 4725 poll_threads(); 4726 CU_ASSERT(g_bserrno == 0); 4727 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4728 bs = g_bs; 4729 4730 for (i = 0; i < 4; i++) { 4731 blob = ut_blob_create_and_open(bs, NULL); 4732 iter_ctx.blobid[i] = spdk_blob_get_id(blob); 4733 4734 /* Just save the blobid as an xattr for testing purposes. */ 4735 rc = spdk_blob_set_xattr(blob, "blobid", &iter_ctx.blobid[i], sizeof(spdk_blob_id)); 4736 CU_ASSERT(rc == 0); 4737 4738 /* Resize the blob */ 4739 spdk_blob_resize(blob, i, blob_op_complete, NULL); 4740 poll_threads(); 4741 CU_ASSERT(g_bserrno == 0); 4742 4743 spdk_blob_close(blob, blob_op_complete, NULL); 4744 poll_threads(); 4745 CU_ASSERT(g_bserrno == 0); 4746 } 4747 4748 g_bserrno = -1; 4749 spdk_bs_unload(bs, bs_op_complete, NULL); 4750 poll_threads(); 4751 CU_ASSERT(g_bserrno == 0); 4752 4753 dev = init_dev(); 4754 spdk_bs_opts_init(&opts, sizeof(opts)); 4755 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4756 opts.iter_cb_fn = test_iter; 4757 opts.iter_cb_arg = &iter_ctx; 4758 4759 /* Test blob iteration during load after a clean shutdown. */ 4760 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4761 poll_threads(); 4762 CU_ASSERT(g_bserrno == 0); 4763 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4764 bs = g_bs; 4765 4766 /* Dirty shutdown */ 4767 bs_free(bs); 4768 4769 dev = init_dev(); 4770 spdk_bs_opts_init(&opts, sizeof(opts)); 4771 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 4772 opts.iter_cb_fn = test_iter; 4773 iter_ctx.current_iter = 0; 4774 opts.iter_cb_arg = &iter_ctx; 4775 4776 /* Test blob iteration during load after a dirty shutdown. */ 4777 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 4778 poll_threads(); 4779 CU_ASSERT(g_bserrno == 0); 4780 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4781 bs = g_bs; 4782 4783 spdk_bs_unload(bs, bs_op_complete, NULL); 4784 poll_threads(); 4785 CU_ASSERT(g_bserrno == 0); 4786 g_bs = NULL; 4787 } 4788 4789 static void 4790 blob_snapshot_rw(void) 4791 { 4792 static const uint8_t zero[10 * 4096] = { 0 }; 4793 struct spdk_blob_store *bs = g_bs; 4794 struct spdk_blob *blob, *snapshot; 4795 struct spdk_io_channel *channel; 4796 struct spdk_blob_opts opts; 4797 spdk_blob_id blobid, snapshotid; 4798 uint64_t free_clusters; 4799 uint64_t cluster_size; 4800 uint64_t page_size; 4801 uint8_t payload_read[10 * 4096]; 4802 uint8_t payload_write[10 * 4096]; 4803 uint64_t write_bytes_start; 4804 uint64_t read_bytes_start; 4805 uint64_t copy_bytes_start; 4806 uint64_t write_bytes; 4807 uint64_t read_bytes; 4808 uint64_t copy_bytes; 4809 4810 free_clusters = spdk_bs_free_cluster_count(bs); 4811 cluster_size = spdk_bs_get_cluster_size(bs); 4812 page_size = spdk_bs_get_page_size(bs); 4813 4814 channel = spdk_bs_alloc_io_channel(bs); 4815 CU_ASSERT(channel != NULL); 4816 4817 ut_spdk_blob_opts_init(&opts); 4818 opts.thin_provision = true; 4819 opts.num_clusters = 5; 4820 4821 blob = ut_blob_create_and_open(bs, &opts); 4822 blobid = spdk_blob_get_id(blob); 4823 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4824 4825 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4826 4827 memset(payload_read, 0xFF, sizeof(payload_read)); 4828 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4829 poll_threads(); 4830 CU_ASSERT(g_bserrno == 0); 4831 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4832 4833 memset(payload_write, 0xE5, sizeof(payload_write)); 4834 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4835 poll_threads(); 4836 CU_ASSERT(g_bserrno == 0); 4837 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4838 4839 /* Create snapshot from blob */ 4840 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4841 poll_threads(); 4842 CU_ASSERT(g_bserrno == 0); 4843 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4844 snapshotid = g_blobid; 4845 4846 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4847 poll_threads(); 4848 CU_ASSERT(g_bserrno == 0); 4849 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4850 snapshot = g_blob; 4851 CU_ASSERT(snapshot->data_ro == true); 4852 CU_ASSERT(snapshot->md_ro == true); 4853 4854 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 4855 4856 write_bytes_start = g_dev_write_bytes; 4857 read_bytes_start = g_dev_read_bytes; 4858 copy_bytes_start = g_dev_copy_bytes; 4859 4860 memset(payload_write, 0xAA, sizeof(payload_write)); 4861 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 4862 poll_threads(); 4863 CU_ASSERT(g_bserrno == 0); 4864 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 4865 4866 /* For a clone we need to allocate and copy one cluster, update one page of metadata 4867 * and then write 10 pages of payload. 4868 */ 4869 write_bytes = g_dev_write_bytes - write_bytes_start; 4870 read_bytes = g_dev_read_bytes - read_bytes_start; 4871 copy_bytes = g_dev_copy_bytes - copy_bytes_start; 4872 if (g_dev_copy_enabled) { 4873 CU_ASSERT(copy_bytes == cluster_size); 4874 } else { 4875 CU_ASSERT(copy_bytes == 0); 4876 } 4877 if (g_use_extent_table) { 4878 /* Add one more page for EXTENT_PAGE write */ 4879 CU_ASSERT(write_bytes + copy_bytes == page_size * 12 + cluster_size); 4880 } else { 4881 CU_ASSERT(write_bytes + copy_bytes == page_size * 11 + cluster_size); 4882 } 4883 CU_ASSERT(read_bytes + copy_bytes == cluster_size); 4884 4885 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 4886 poll_threads(); 4887 CU_ASSERT(g_bserrno == 0); 4888 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4889 4890 /* Data on snapshot should not change after write to clone */ 4891 memset(payload_write, 0xE5, sizeof(payload_write)); 4892 spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL); 4893 poll_threads(); 4894 CU_ASSERT(g_bserrno == 0); 4895 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4896 4897 ut_blob_close_and_delete(bs, blob); 4898 ut_blob_close_and_delete(bs, snapshot); 4899 4900 spdk_bs_free_io_channel(channel); 4901 poll_threads(); 4902 g_blob = NULL; 4903 g_blobid = 0; 4904 } 4905 4906 static void 4907 blob_snapshot_rw_iov(void) 4908 { 4909 static const uint8_t zero[10 * 4096] = { 0 }; 4910 struct spdk_blob_store *bs = g_bs; 4911 struct spdk_blob *blob, *snapshot; 4912 struct spdk_io_channel *channel; 4913 struct spdk_blob_opts opts; 4914 spdk_blob_id blobid, snapshotid; 4915 uint64_t free_clusters; 4916 uint8_t payload_read[10 * 4096]; 4917 uint8_t payload_write[10 * 4096]; 4918 struct iovec iov_read[3]; 4919 struct iovec iov_write[3]; 4920 4921 free_clusters = spdk_bs_free_cluster_count(bs); 4922 4923 channel = spdk_bs_alloc_io_channel(bs); 4924 CU_ASSERT(channel != NULL); 4925 4926 ut_spdk_blob_opts_init(&opts); 4927 opts.thin_provision = true; 4928 opts.num_clusters = 5; 4929 4930 blob = ut_blob_create_and_open(bs, &opts); 4931 blobid = spdk_blob_get_id(blob); 4932 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 4933 4934 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 4935 4936 /* Create snapshot from blob */ 4937 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4938 poll_threads(); 4939 CU_ASSERT(g_bserrno == 0); 4940 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4941 snapshotid = g_blobid; 4942 4943 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4944 poll_threads(); 4945 CU_ASSERT(g_bserrno == 0); 4946 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4947 snapshot = g_blob; 4948 CU_ASSERT(snapshot->data_ro == true); 4949 CU_ASSERT(snapshot->md_ro == true); 4950 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 4951 4952 /* Payload should be all zeros from unallocated clusters */ 4953 memset(payload_read, 0xAA, sizeof(payload_read)); 4954 iov_read[0].iov_base = payload_read; 4955 iov_read[0].iov_len = 3 * 4096; 4956 iov_read[1].iov_base = payload_read + 3 * 4096; 4957 iov_read[1].iov_len = 4 * 4096; 4958 iov_read[2].iov_base = payload_read + 7 * 4096; 4959 iov_read[2].iov_len = 3 * 4096; 4960 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4961 poll_threads(); 4962 CU_ASSERT(g_bserrno == 0); 4963 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 4964 4965 memset(payload_write, 0xE5, sizeof(payload_write)); 4966 iov_write[0].iov_base = payload_write; 4967 iov_write[0].iov_len = 1 * 4096; 4968 iov_write[1].iov_base = payload_write + 1 * 4096; 4969 iov_write[1].iov_len = 5 * 4096; 4970 iov_write[2].iov_base = payload_write + 6 * 4096; 4971 iov_write[2].iov_len = 4 * 4096; 4972 4973 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 4974 poll_threads(); 4975 CU_ASSERT(g_bserrno == 0); 4976 4977 memset(payload_read, 0xAA, sizeof(payload_read)); 4978 iov_read[0].iov_base = payload_read; 4979 iov_read[0].iov_len = 3 * 4096; 4980 iov_read[1].iov_base = payload_read + 3 * 4096; 4981 iov_read[1].iov_len = 4 * 4096; 4982 iov_read[2].iov_base = payload_read + 7 * 4096; 4983 iov_read[2].iov_len = 3 * 4096; 4984 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 4985 poll_threads(); 4986 CU_ASSERT(g_bserrno == 0); 4987 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 4988 4989 spdk_bs_free_io_channel(channel); 4990 poll_threads(); 4991 4992 ut_blob_close_and_delete(bs, blob); 4993 ut_blob_close_and_delete(bs, snapshot); 4994 } 4995 4996 /** 4997 * Inflate / decouple parent rw unit tests. 4998 * 4999 * -------------- 5000 * original blob: 0 1 2 3 4 5001 * ,---------+---------+---------+---------+---------. 5002 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 5003 * +---------+---------+---------+---------+---------+ 5004 * snapshot2 | - |yyyyyyyyy| - |yyyyyyyyy| - | 5005 * +---------+---------+---------+---------+---------+ 5006 * blob | - |zzzzzzzzz| - | - | - | 5007 * '---------+---------+---------+---------+---------' 5008 * . . . . . . 5009 * -------- . . . . . . 5010 * inflate: . . . . . . 5011 * ,---------+---------+---------+---------+---------. 5012 * blob |xxxxxxxxx|zzzzzzzzz|xxxxxxxxx|yyyyyyyyy|000000000| 5013 * '---------+---------+---------+---------+---------' 5014 * 5015 * NOTE: needs to allocate 4 clusters, thin provisioning removed, dependency 5016 * on snapshot2 and snapshot removed . . . 5017 * . . . . . . 5018 * ---------------- . . . . . . 5019 * decouple parent: . . . . . . 5020 * ,---------+---------+---------+---------+---------. 5021 * snapshot |xxxxxxxxx|xxxxxxxxx|xxxxxxxxx|xxxxxxxxx| - | 5022 * +---------+---------+---------+---------+---------+ 5023 * blob | - |zzzzzzzzz| - |yyyyyyyyy| - | 5024 * '---------+---------+---------+---------+---------' 5025 * 5026 * NOTE: needs to allocate 1 cluster, 3 clusters unallocated, dependency 5027 * on snapshot2 removed and on snapshot still exists. Snapshot2 5028 * should remain a clone of snapshot. 5029 */ 5030 static void 5031 _blob_inflate_rw(bool decouple_parent) 5032 { 5033 struct spdk_blob_store *bs = g_bs; 5034 struct spdk_blob *blob, *snapshot, *snapshot2; 5035 struct spdk_io_channel *channel; 5036 struct spdk_blob_opts opts; 5037 spdk_blob_id blobid, snapshotid, snapshot2id; 5038 uint64_t free_clusters; 5039 uint64_t cluster_size; 5040 5041 uint64_t payload_size; 5042 uint8_t *payload_read; 5043 uint8_t *payload_write; 5044 uint8_t *payload_clone; 5045 5046 uint64_t pages_per_cluster; 5047 uint64_t pages_per_payload; 5048 5049 int i; 5050 spdk_blob_id ids[2]; 5051 size_t count; 5052 5053 free_clusters = spdk_bs_free_cluster_count(bs); 5054 cluster_size = spdk_bs_get_cluster_size(bs); 5055 pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs); 5056 pages_per_payload = pages_per_cluster * 5; 5057 5058 payload_size = cluster_size * 5; 5059 5060 payload_read = malloc(payload_size); 5061 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 5062 5063 payload_write = malloc(payload_size); 5064 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 5065 5066 payload_clone = malloc(payload_size); 5067 SPDK_CU_ASSERT_FATAL(payload_clone != NULL); 5068 5069 channel = spdk_bs_alloc_io_channel(bs); 5070 SPDK_CU_ASSERT_FATAL(channel != NULL); 5071 5072 /* Create blob */ 5073 ut_spdk_blob_opts_init(&opts); 5074 opts.thin_provision = true; 5075 opts.num_clusters = 5; 5076 5077 blob = ut_blob_create_and_open(bs, &opts); 5078 blobid = spdk_blob_get_id(blob); 5079 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 5080 5081 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5082 5083 /* 1) Initial read should return zeroed payload */ 5084 memset(payload_read, 0xFF, payload_size); 5085 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5086 blob_op_complete, NULL); 5087 poll_threads(); 5088 CU_ASSERT(g_bserrno == 0); 5089 CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size)); 5090 5091 /* Fill whole blob with a pattern, except last cluster (to be sure it 5092 * isn't allocated) */ 5093 memset(payload_write, 0xE5, payload_size - cluster_size); 5094 spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload - 5095 pages_per_cluster, blob_op_complete, NULL); 5096 poll_threads(); 5097 CU_ASSERT(g_bserrno == 0); 5098 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5099 5100 /* 2) Create snapshot from blob (first level) */ 5101 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5102 poll_threads(); 5103 CU_ASSERT(g_bserrno == 0); 5104 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5105 snapshotid = g_blobid; 5106 5107 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5108 poll_threads(); 5109 CU_ASSERT(g_bserrno == 0); 5110 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5111 snapshot = g_blob; 5112 CU_ASSERT(snapshot->data_ro == true); 5113 CU_ASSERT(snapshot->md_ro == true); 5114 5115 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 5116 5117 /* Write every second cluster with a pattern. 5118 * 5119 * Last cluster shouldn't be written, to be sure that snapshot nor clone 5120 * doesn't allocate it. 5121 * 5122 * payload_clone stores expected result on "blob" read at the time and 5123 * is used only to check data consistency on clone before and after 5124 * inflation. Initially we fill it with a backing snapshots pattern 5125 * used before. 5126 */ 5127 memset(payload_clone, 0xE5, payload_size - cluster_size); 5128 memset(payload_clone + payload_size - cluster_size, 0x00, cluster_size); 5129 memset(payload_write, 0xAA, payload_size); 5130 for (i = 1; i < 5; i += 2) { 5131 spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster, 5132 pages_per_cluster, blob_op_complete, NULL); 5133 poll_threads(); 5134 CU_ASSERT(g_bserrno == 0); 5135 5136 /* Update expected result */ 5137 memcpy(payload_clone + (cluster_size * i), payload_write, 5138 cluster_size); 5139 } 5140 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 5141 5142 /* Check data consistency on clone */ 5143 memset(payload_read, 0xFF, payload_size); 5144 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5145 blob_op_complete, NULL); 5146 poll_threads(); 5147 CU_ASSERT(g_bserrno == 0); 5148 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5149 5150 /* 3) Create second levels snapshot from blob */ 5151 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5152 poll_threads(); 5153 CU_ASSERT(g_bserrno == 0); 5154 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5155 snapshot2id = g_blobid; 5156 5157 spdk_bs_open_blob(bs, snapshot2id, blob_op_with_handle_complete, NULL); 5158 poll_threads(); 5159 CU_ASSERT(g_bserrno == 0); 5160 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5161 snapshot2 = g_blob; 5162 CU_ASSERT(snapshot2->data_ro == true); 5163 CU_ASSERT(snapshot2->md_ro == true); 5164 5165 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 5); 5166 5167 CU_ASSERT(snapshot2->parent_id == snapshotid); 5168 5169 /* Write one cluster on the top level blob. This cluster (1) covers 5170 * already allocated cluster in the snapshot2, so shouldn't be inflated 5171 * at all */ 5172 spdk_blob_io_write(blob, channel, payload_write, pages_per_cluster, 5173 pages_per_cluster, blob_op_complete, NULL); 5174 poll_threads(); 5175 CU_ASSERT(g_bserrno == 0); 5176 5177 /* Update expected result */ 5178 memcpy(payload_clone + cluster_size, payload_write, cluster_size); 5179 5180 /* Check data consistency on clone */ 5181 memset(payload_read, 0xFF, payload_size); 5182 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5183 blob_op_complete, NULL); 5184 poll_threads(); 5185 CU_ASSERT(g_bserrno == 0); 5186 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5187 5188 5189 /* Close all blobs */ 5190 spdk_blob_close(blob, blob_op_complete, NULL); 5191 poll_threads(); 5192 CU_ASSERT(g_bserrno == 0); 5193 5194 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5195 poll_threads(); 5196 CU_ASSERT(g_bserrno == 0); 5197 5198 spdk_blob_close(snapshot, blob_op_complete, NULL); 5199 poll_threads(); 5200 CU_ASSERT(g_bserrno == 0); 5201 5202 /* Check snapshot-clone relations */ 5203 count = 2; 5204 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5205 CU_ASSERT(count == 1); 5206 CU_ASSERT(ids[0] == snapshot2id); 5207 5208 count = 2; 5209 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5210 CU_ASSERT(count == 1); 5211 CU_ASSERT(ids[0] == blobid); 5212 5213 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshot2id); 5214 5215 free_clusters = spdk_bs_free_cluster_count(bs); 5216 if (!decouple_parent) { 5217 /* Do full blob inflation */ 5218 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 5219 poll_threads(); 5220 CU_ASSERT(g_bserrno == 0); 5221 5222 /* All clusters should be inflated (except one already allocated 5223 * in a top level blob) */ 5224 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 4); 5225 5226 /* Check if relation tree updated correctly */ 5227 count = 2; 5228 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5229 5230 /* snapshotid have one clone */ 5231 CU_ASSERT(count == 1); 5232 CU_ASSERT(ids[0] == snapshot2id); 5233 5234 /* snapshot2id have no clones */ 5235 count = 2; 5236 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5237 CU_ASSERT(count == 0); 5238 5239 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5240 } else { 5241 /* Decouple parent of blob */ 5242 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 5243 poll_threads(); 5244 CU_ASSERT(g_bserrno == 0); 5245 5246 /* Only one cluster from a parent should be inflated (second one 5247 * is covered by a cluster written on a top level blob, and 5248 * already allocated) */ 5249 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 1); 5250 5251 /* Check if relation tree updated correctly */ 5252 count = 2; 5253 CU_ASSERT(spdk_blob_get_clones(bs, snapshotid, ids, &count) == 0); 5254 5255 /* snapshotid have two clones now */ 5256 CU_ASSERT(count == 2); 5257 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5258 CU_ASSERT(ids[0] == snapshot2id || ids[1] == snapshot2id); 5259 5260 /* snapshot2id have no clones */ 5261 count = 2; 5262 CU_ASSERT(spdk_blob_get_clones(bs, snapshot2id, ids, &count) == 0); 5263 CU_ASSERT(count == 0); 5264 5265 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5266 } 5267 5268 /* Try to delete snapshot2 (should pass) */ 5269 spdk_bs_delete_blob(bs, snapshot2id, blob_op_complete, NULL); 5270 poll_threads(); 5271 CU_ASSERT(g_bserrno == 0); 5272 5273 /* Try to delete base snapshot */ 5274 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5275 poll_threads(); 5276 CU_ASSERT(g_bserrno == 0); 5277 5278 /* Reopen blob after snapshot deletion */ 5279 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 5280 poll_threads(); 5281 CU_ASSERT(g_bserrno == 0); 5282 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5283 blob = g_blob; 5284 5285 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 5286 5287 /* Check data consistency on inflated blob */ 5288 memset(payload_read, 0xFF, payload_size); 5289 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 5290 blob_op_complete, NULL); 5291 poll_threads(); 5292 CU_ASSERT(g_bserrno == 0); 5293 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 5294 5295 spdk_bs_free_io_channel(channel); 5296 poll_threads(); 5297 5298 free(payload_read); 5299 free(payload_write); 5300 free(payload_clone); 5301 5302 ut_blob_close_and_delete(bs, blob); 5303 } 5304 5305 static void 5306 blob_inflate_rw(void) 5307 { 5308 _blob_inflate_rw(false); 5309 _blob_inflate_rw(true); 5310 } 5311 5312 /** 5313 * Snapshot-clones relation test 5314 * 5315 * snapshot 5316 * | 5317 * +-----+-----+ 5318 * | | 5319 * blob(ro) snapshot2 5320 * | | 5321 * clone2 clone 5322 */ 5323 static void 5324 blob_relations(void) 5325 { 5326 struct spdk_blob_store *bs; 5327 struct spdk_bs_dev *dev; 5328 struct spdk_bs_opts bs_opts; 5329 struct spdk_blob_opts opts; 5330 struct spdk_blob *blob, *snapshot, *snapshot2, *clone, *clone2; 5331 spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2; 5332 int rc; 5333 size_t count; 5334 spdk_blob_id ids[10] = {}; 5335 5336 dev = init_dev(); 5337 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 5338 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5339 5340 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 5341 poll_threads(); 5342 CU_ASSERT(g_bserrno == 0); 5343 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5344 bs = g_bs; 5345 5346 /* 1. Create blob with 10 clusters */ 5347 5348 ut_spdk_blob_opts_init(&opts); 5349 opts.num_clusters = 10; 5350 5351 blob = ut_blob_create_and_open(bs, &opts); 5352 blobid = spdk_blob_get_id(blob); 5353 5354 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5355 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5356 CU_ASSERT(!spdk_blob_is_clone(blob)); 5357 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob)); 5358 5359 /* blob should not have underlying snapshot nor clones */ 5360 CU_ASSERT(blob->parent_id == SPDK_BLOBID_INVALID); 5361 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 5362 count = SPDK_COUNTOF(ids); 5363 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5364 CU_ASSERT(rc == 0); 5365 CU_ASSERT(count == 0); 5366 5367 5368 /* 2. Create snapshot */ 5369 5370 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5371 poll_threads(); 5372 CU_ASSERT(g_bserrno == 0); 5373 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5374 snapshotid = g_blobid; 5375 5376 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 5377 poll_threads(); 5378 CU_ASSERT(g_bserrno == 0); 5379 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5380 snapshot = g_blob; 5381 5382 CU_ASSERT(spdk_blob_is_read_only(snapshot)); 5383 CU_ASSERT(spdk_blob_is_snapshot(snapshot)); 5384 CU_ASSERT(!spdk_blob_is_clone(snapshot)); 5385 CU_ASSERT(snapshot->parent_id == SPDK_BLOBID_INVALID); 5386 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5387 5388 /* Check if original blob is converted to the clone of snapshot */ 5389 CU_ASSERT(!spdk_blob_is_read_only(blob)); 5390 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5391 CU_ASSERT(spdk_blob_is_clone(blob)); 5392 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5393 CU_ASSERT(blob->parent_id == snapshotid); 5394 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5395 5396 count = SPDK_COUNTOF(ids); 5397 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5398 CU_ASSERT(rc == 0); 5399 CU_ASSERT(count == 1); 5400 CU_ASSERT(ids[0] == blobid); 5401 5402 5403 /* 3. Create clone from snapshot */ 5404 5405 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 5406 poll_threads(); 5407 CU_ASSERT(g_bserrno == 0); 5408 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5409 cloneid = g_blobid; 5410 5411 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 5412 poll_threads(); 5413 CU_ASSERT(g_bserrno == 0); 5414 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5415 clone = g_blob; 5416 5417 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5418 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5419 CU_ASSERT(spdk_blob_is_clone(clone)); 5420 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5421 CU_ASSERT(clone->parent_id == snapshotid); 5422 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 5423 5424 count = SPDK_COUNTOF(ids); 5425 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5426 CU_ASSERT(rc == 0); 5427 CU_ASSERT(count == 0); 5428 5429 /* Check if clone is on the snapshot's list */ 5430 count = SPDK_COUNTOF(ids); 5431 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5432 CU_ASSERT(rc == 0); 5433 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5434 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 5435 5436 5437 /* 4. Create snapshot of the clone */ 5438 5439 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 5440 poll_threads(); 5441 CU_ASSERT(g_bserrno == 0); 5442 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5443 snapshotid2 = g_blobid; 5444 5445 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 5446 poll_threads(); 5447 CU_ASSERT(g_bserrno == 0); 5448 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5449 snapshot2 = g_blob; 5450 5451 CU_ASSERT(spdk_blob_is_read_only(snapshot2)); 5452 CU_ASSERT(spdk_blob_is_snapshot(snapshot2)); 5453 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 5454 CU_ASSERT(snapshot2->parent_id == snapshotid); 5455 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5456 5457 /* Check if clone is converted to the clone of snapshot2 and snapshot2 5458 * is a child of snapshot */ 5459 CU_ASSERT(!spdk_blob_is_read_only(clone)); 5460 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 5461 CU_ASSERT(spdk_blob_is_clone(clone)); 5462 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 5463 CU_ASSERT(clone->parent_id == snapshotid2); 5464 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5465 5466 count = SPDK_COUNTOF(ids); 5467 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5468 CU_ASSERT(rc == 0); 5469 CU_ASSERT(count == 1); 5470 CU_ASSERT(ids[0] == cloneid); 5471 5472 5473 /* 5. Try to create clone from read only blob */ 5474 5475 /* Mark blob as read only */ 5476 spdk_blob_set_read_only(blob); 5477 spdk_blob_sync_md(blob, blob_op_complete, NULL); 5478 poll_threads(); 5479 CU_ASSERT(g_bserrno == 0); 5480 5481 /* Check if previously created blob is read only clone */ 5482 CU_ASSERT(spdk_blob_is_read_only(blob)); 5483 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 5484 CU_ASSERT(spdk_blob_is_clone(blob)); 5485 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 5486 5487 /* Create clone from read only blob */ 5488 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5489 poll_threads(); 5490 CU_ASSERT(g_bserrno == 0); 5491 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5492 cloneid2 = g_blobid; 5493 5494 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 5495 poll_threads(); 5496 CU_ASSERT(g_bserrno == 0); 5497 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5498 clone2 = g_blob; 5499 5500 CU_ASSERT(!spdk_blob_is_read_only(clone2)); 5501 CU_ASSERT(!spdk_blob_is_snapshot(clone2)); 5502 CU_ASSERT(spdk_blob_is_clone(clone2)); 5503 CU_ASSERT(spdk_blob_is_thin_provisioned(clone2)); 5504 5505 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5506 5507 count = SPDK_COUNTOF(ids); 5508 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5509 CU_ASSERT(rc == 0); 5510 5511 CU_ASSERT(count == 1); 5512 CU_ASSERT(ids[0] == cloneid2); 5513 5514 /* Close blobs */ 5515 5516 spdk_blob_close(clone2, blob_op_complete, NULL); 5517 poll_threads(); 5518 CU_ASSERT(g_bserrno == 0); 5519 5520 spdk_blob_close(blob, blob_op_complete, NULL); 5521 poll_threads(); 5522 CU_ASSERT(g_bserrno == 0); 5523 5524 spdk_blob_close(clone, blob_op_complete, NULL); 5525 poll_threads(); 5526 CU_ASSERT(g_bserrno == 0); 5527 5528 spdk_blob_close(snapshot, blob_op_complete, NULL); 5529 poll_threads(); 5530 CU_ASSERT(g_bserrno == 0); 5531 5532 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5533 poll_threads(); 5534 CU_ASSERT(g_bserrno == 0); 5535 5536 /* Try to delete snapshot with more than 1 clone */ 5537 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5538 poll_threads(); 5539 CU_ASSERT(g_bserrno != 0); 5540 5541 ut_bs_reload(&bs, &bs_opts); 5542 5543 /* NULL ids array should return number of clones in count */ 5544 count = SPDK_COUNTOF(ids); 5545 rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count); 5546 CU_ASSERT(rc == -ENOMEM); 5547 CU_ASSERT(count == 2); 5548 5549 /* incorrect array size */ 5550 count = 1; 5551 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5552 CU_ASSERT(rc == -ENOMEM); 5553 CU_ASSERT(count == 2); 5554 5555 5556 /* Verify structure of loaded blob store */ 5557 5558 /* snapshot */ 5559 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 5560 5561 count = SPDK_COUNTOF(ids); 5562 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 5563 CU_ASSERT(rc == 0); 5564 CU_ASSERT(count == 2); 5565 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5566 CU_ASSERT(ids[0] == snapshotid2 || ids[1] == snapshotid2); 5567 5568 /* blob */ 5569 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 5570 count = SPDK_COUNTOF(ids); 5571 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5572 CU_ASSERT(rc == 0); 5573 CU_ASSERT(count == 1); 5574 CU_ASSERT(ids[0] == cloneid2); 5575 5576 /* clone */ 5577 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5578 count = SPDK_COUNTOF(ids); 5579 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5580 CU_ASSERT(rc == 0); 5581 CU_ASSERT(count == 0); 5582 5583 /* snapshot2 */ 5584 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid); 5585 count = SPDK_COUNTOF(ids); 5586 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5587 CU_ASSERT(rc == 0); 5588 CU_ASSERT(count == 1); 5589 CU_ASSERT(ids[0] == cloneid); 5590 5591 /* clone2 */ 5592 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5593 count = SPDK_COUNTOF(ids); 5594 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 5595 CU_ASSERT(rc == 0); 5596 CU_ASSERT(count == 0); 5597 5598 /* Try to delete blob that user should not be able to remove */ 5599 5600 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5601 poll_threads(); 5602 CU_ASSERT(g_bserrno != 0); 5603 5604 /* Remove all blobs */ 5605 5606 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 5607 poll_threads(); 5608 CU_ASSERT(g_bserrno == 0); 5609 5610 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5611 poll_threads(); 5612 CU_ASSERT(g_bserrno == 0); 5613 5614 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 5615 poll_threads(); 5616 CU_ASSERT(g_bserrno == 0); 5617 5618 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5619 poll_threads(); 5620 CU_ASSERT(g_bserrno == 0); 5621 5622 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 5623 poll_threads(); 5624 CU_ASSERT(g_bserrno == 0); 5625 5626 spdk_bs_unload(bs, bs_op_complete, NULL); 5627 poll_threads(); 5628 CU_ASSERT(g_bserrno == 0); 5629 5630 g_bs = NULL; 5631 } 5632 5633 /** 5634 * Snapshot-clones relation test 2 5635 * 5636 * snapshot1 5637 * | 5638 * snapshot2 5639 * | 5640 * +-----+-----+ 5641 * | | 5642 * blob(ro) snapshot3 5643 * | | 5644 * | snapshot4 5645 * | | | 5646 * clone2 clone clone3 5647 */ 5648 static void 5649 blob_relations2(void) 5650 { 5651 struct spdk_blob_store *bs; 5652 struct spdk_bs_dev *dev; 5653 struct spdk_bs_opts bs_opts; 5654 struct spdk_blob_opts opts; 5655 struct spdk_blob *blob, *snapshot1, *snapshot2, *snapshot3, *snapshot4, *clone, *clone2; 5656 spdk_blob_id blobid, snapshotid1, snapshotid2, snapshotid3, snapshotid4, cloneid, cloneid2, 5657 cloneid3; 5658 int rc; 5659 size_t count; 5660 spdk_blob_id ids[10] = {}; 5661 5662 dev = init_dev(); 5663 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 5664 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 5665 5666 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 5667 poll_threads(); 5668 CU_ASSERT(g_bserrno == 0); 5669 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 5670 bs = g_bs; 5671 5672 /* 1. Create blob with 10 clusters */ 5673 5674 ut_spdk_blob_opts_init(&opts); 5675 opts.num_clusters = 10; 5676 5677 blob = ut_blob_create_and_open(bs, &opts); 5678 blobid = spdk_blob_get_id(blob); 5679 5680 /* 2. Create snapshot1 */ 5681 5682 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5683 poll_threads(); 5684 CU_ASSERT(g_bserrno == 0); 5685 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5686 snapshotid1 = g_blobid; 5687 5688 spdk_bs_open_blob(bs, snapshotid1, blob_op_with_handle_complete, NULL); 5689 poll_threads(); 5690 CU_ASSERT(g_bserrno == 0); 5691 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5692 snapshot1 = g_blob; 5693 5694 CU_ASSERT(snapshot1->parent_id == SPDK_BLOBID_INVALID); 5695 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid1) == SPDK_BLOBID_INVALID); 5696 5697 CU_ASSERT(blob->parent_id == snapshotid1); 5698 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1); 5699 5700 /* Check if blob is the clone of snapshot1 */ 5701 CU_ASSERT(blob->parent_id == snapshotid1); 5702 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid1); 5703 5704 count = SPDK_COUNTOF(ids); 5705 rc = spdk_blob_get_clones(bs, snapshotid1, ids, &count); 5706 CU_ASSERT(rc == 0); 5707 CU_ASSERT(count == 1); 5708 CU_ASSERT(ids[0] == blobid); 5709 5710 /* 3. Create another snapshot */ 5711 5712 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5713 poll_threads(); 5714 CU_ASSERT(g_bserrno == 0); 5715 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5716 snapshotid2 = g_blobid; 5717 5718 spdk_bs_open_blob(bs, snapshotid2, blob_op_with_handle_complete, NULL); 5719 poll_threads(); 5720 CU_ASSERT(g_bserrno == 0); 5721 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5722 snapshot2 = g_blob; 5723 5724 CU_ASSERT(spdk_blob_is_clone(snapshot2)); 5725 CU_ASSERT(snapshot2->parent_id == snapshotid1); 5726 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == snapshotid1); 5727 5728 /* Check if snapshot2 is the clone of snapshot1 and blob 5729 * is a child of snapshot2 */ 5730 CU_ASSERT(blob->parent_id == snapshotid2); 5731 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2); 5732 5733 count = SPDK_COUNTOF(ids); 5734 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5735 CU_ASSERT(rc == 0); 5736 CU_ASSERT(count == 1); 5737 CU_ASSERT(ids[0] == blobid); 5738 5739 /* 4. Create clone from snapshot */ 5740 5741 spdk_bs_create_clone(bs, snapshotid2, NULL, blob_op_with_id_complete, NULL); 5742 poll_threads(); 5743 CU_ASSERT(g_bserrno == 0); 5744 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5745 cloneid = g_blobid; 5746 5747 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 5748 poll_threads(); 5749 CU_ASSERT(g_bserrno == 0); 5750 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5751 clone = g_blob; 5752 5753 CU_ASSERT(clone->parent_id == snapshotid2); 5754 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid2); 5755 5756 /* Check if clone is on the snapshot's list */ 5757 count = SPDK_COUNTOF(ids); 5758 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5759 CU_ASSERT(rc == 0); 5760 CU_ASSERT(count == 2); 5761 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5762 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 5763 5764 /* 5. Create snapshot of the clone */ 5765 5766 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 5767 poll_threads(); 5768 CU_ASSERT(g_bserrno == 0); 5769 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5770 snapshotid3 = g_blobid; 5771 5772 spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL); 5773 poll_threads(); 5774 CU_ASSERT(g_bserrno == 0); 5775 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5776 snapshot3 = g_blob; 5777 5778 CU_ASSERT(snapshot3->parent_id == snapshotid2); 5779 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2); 5780 5781 /* Check if clone is converted to the clone of snapshot3 and snapshot3 5782 * is a child of snapshot2 */ 5783 CU_ASSERT(clone->parent_id == snapshotid3); 5784 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 5785 5786 count = SPDK_COUNTOF(ids); 5787 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 5788 CU_ASSERT(rc == 0); 5789 CU_ASSERT(count == 1); 5790 CU_ASSERT(ids[0] == cloneid); 5791 5792 /* 6. Create another snapshot of the clone */ 5793 5794 spdk_bs_create_snapshot(bs, cloneid, NULL, blob_op_with_id_complete, NULL); 5795 poll_threads(); 5796 CU_ASSERT(g_bserrno == 0); 5797 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5798 snapshotid4 = g_blobid; 5799 5800 spdk_bs_open_blob(bs, snapshotid4, blob_op_with_handle_complete, NULL); 5801 poll_threads(); 5802 CU_ASSERT(g_bserrno == 0); 5803 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5804 snapshot4 = g_blob; 5805 5806 CU_ASSERT(snapshot4->parent_id == snapshotid3); 5807 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid4) == snapshotid3); 5808 5809 /* Check if clone is converted to the clone of snapshot4 and snapshot4 5810 * is a child of snapshot3 */ 5811 CU_ASSERT(clone->parent_id == snapshotid4); 5812 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid4); 5813 5814 count = SPDK_COUNTOF(ids); 5815 rc = spdk_blob_get_clones(bs, snapshotid4, ids, &count); 5816 CU_ASSERT(rc == 0); 5817 CU_ASSERT(count == 1); 5818 CU_ASSERT(ids[0] == cloneid); 5819 5820 /* 7. Remove snapshot 4 */ 5821 5822 ut_blob_close_and_delete(bs, snapshot4); 5823 5824 /* Check if relations are back to state from before creating snapshot 4 */ 5825 CU_ASSERT(clone->parent_id == snapshotid3); 5826 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 5827 5828 count = SPDK_COUNTOF(ids); 5829 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 5830 CU_ASSERT(rc == 0); 5831 CU_ASSERT(count == 1); 5832 CU_ASSERT(ids[0] == cloneid); 5833 5834 /* 8. Create second clone of snapshot 3 and try to remove snapshot 3 */ 5835 5836 spdk_bs_create_clone(bs, snapshotid3, NULL, blob_op_with_id_complete, NULL); 5837 poll_threads(); 5838 CU_ASSERT(g_bserrno == 0); 5839 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5840 cloneid3 = g_blobid; 5841 5842 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 5843 poll_threads(); 5844 CU_ASSERT(g_bserrno != 0); 5845 5846 /* 9. Open snapshot 3 again and try to remove it while clone 3 is closed */ 5847 5848 spdk_bs_open_blob(bs, snapshotid3, blob_op_with_handle_complete, NULL); 5849 poll_threads(); 5850 CU_ASSERT(g_bserrno == 0); 5851 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5852 snapshot3 = g_blob; 5853 5854 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 5855 poll_threads(); 5856 CU_ASSERT(g_bserrno != 0); 5857 5858 spdk_blob_close(snapshot3, blob_op_complete, NULL); 5859 poll_threads(); 5860 CU_ASSERT(g_bserrno == 0); 5861 5862 spdk_bs_delete_blob(bs, cloneid3, blob_op_complete, NULL); 5863 poll_threads(); 5864 CU_ASSERT(g_bserrno == 0); 5865 5866 /* 10. Remove snapshot 1 */ 5867 5868 ut_blob_close_and_delete(bs, snapshot1); 5869 5870 /* Check if relations are back to state from before creating snapshot 4 (before step 6) */ 5871 CU_ASSERT(snapshot2->parent_id == SPDK_BLOBID_INVALID); 5872 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID); 5873 5874 count = SPDK_COUNTOF(ids); 5875 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5876 CU_ASSERT(rc == 0); 5877 CU_ASSERT(count == 2); 5878 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5879 CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3); 5880 5881 /* 11. Try to create clone from read only blob */ 5882 5883 /* Mark blob as read only */ 5884 spdk_blob_set_read_only(blob); 5885 spdk_blob_sync_md(blob, blob_op_complete, NULL); 5886 poll_threads(); 5887 CU_ASSERT(g_bserrno == 0); 5888 5889 /* Create clone from read only blob */ 5890 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 5891 poll_threads(); 5892 CU_ASSERT(g_bserrno == 0); 5893 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 5894 cloneid2 = g_blobid; 5895 5896 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 5897 poll_threads(); 5898 CU_ASSERT(g_bserrno == 0); 5899 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 5900 clone2 = g_blob; 5901 5902 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5903 5904 count = SPDK_COUNTOF(ids); 5905 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5906 CU_ASSERT(rc == 0); 5907 CU_ASSERT(count == 1); 5908 CU_ASSERT(ids[0] == cloneid2); 5909 5910 /* Close blobs */ 5911 5912 spdk_blob_close(clone2, blob_op_complete, NULL); 5913 poll_threads(); 5914 CU_ASSERT(g_bserrno == 0); 5915 5916 spdk_blob_close(blob, blob_op_complete, NULL); 5917 poll_threads(); 5918 CU_ASSERT(g_bserrno == 0); 5919 5920 spdk_blob_close(clone, blob_op_complete, NULL); 5921 poll_threads(); 5922 CU_ASSERT(g_bserrno == 0); 5923 5924 spdk_blob_close(snapshot2, blob_op_complete, NULL); 5925 poll_threads(); 5926 CU_ASSERT(g_bserrno == 0); 5927 5928 spdk_blob_close(snapshot3, blob_op_complete, NULL); 5929 poll_threads(); 5930 CU_ASSERT(g_bserrno == 0); 5931 5932 ut_bs_reload(&bs, &bs_opts); 5933 5934 /* Verify structure of loaded blob store */ 5935 5936 /* snapshot2 */ 5937 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid2) == SPDK_BLOBID_INVALID); 5938 5939 count = SPDK_COUNTOF(ids); 5940 rc = spdk_blob_get_clones(bs, snapshotid2, ids, &count); 5941 CU_ASSERT(rc == 0); 5942 CU_ASSERT(count == 2); 5943 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 5944 CU_ASSERT(ids[0] == snapshotid3 || ids[1] == snapshotid3); 5945 5946 /* blob */ 5947 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid2); 5948 count = SPDK_COUNTOF(ids); 5949 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 5950 CU_ASSERT(rc == 0); 5951 CU_ASSERT(count == 1); 5952 CU_ASSERT(ids[0] == cloneid2); 5953 5954 /* clone */ 5955 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid3); 5956 count = SPDK_COUNTOF(ids); 5957 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 5958 CU_ASSERT(rc == 0); 5959 CU_ASSERT(count == 0); 5960 5961 /* snapshot3 */ 5962 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid3) == snapshotid2); 5963 count = SPDK_COUNTOF(ids); 5964 rc = spdk_blob_get_clones(bs, snapshotid3, ids, &count); 5965 CU_ASSERT(rc == 0); 5966 CU_ASSERT(count == 1); 5967 CU_ASSERT(ids[0] == cloneid); 5968 5969 /* clone2 */ 5970 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 5971 count = SPDK_COUNTOF(ids); 5972 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 5973 CU_ASSERT(rc == 0); 5974 CU_ASSERT(count == 0); 5975 5976 /* Try to delete all blobs in the worse possible order */ 5977 5978 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5979 poll_threads(); 5980 CU_ASSERT(g_bserrno != 0); 5981 5982 spdk_bs_delete_blob(bs, snapshotid3, blob_op_complete, NULL); 5983 poll_threads(); 5984 CU_ASSERT(g_bserrno == 0); 5985 5986 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5987 poll_threads(); 5988 CU_ASSERT(g_bserrno != 0); 5989 5990 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 5991 poll_threads(); 5992 CU_ASSERT(g_bserrno == 0); 5993 5994 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 5995 poll_threads(); 5996 CU_ASSERT(g_bserrno == 0); 5997 5998 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 5999 poll_threads(); 6000 CU_ASSERT(g_bserrno == 0); 6001 6002 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 6003 poll_threads(); 6004 CU_ASSERT(g_bserrno == 0); 6005 6006 spdk_bs_unload(bs, bs_op_complete, NULL); 6007 poll_threads(); 6008 CU_ASSERT(g_bserrno == 0); 6009 6010 g_bs = NULL; 6011 } 6012 6013 /** 6014 * Snapshot-clones relation test 3 6015 * 6016 * snapshot0 6017 * | 6018 * snapshot1 6019 * | 6020 * snapshot2 6021 * | 6022 * blob 6023 */ 6024 static void 6025 blob_relations3(void) 6026 { 6027 struct spdk_blob_store *bs; 6028 struct spdk_bs_dev *dev; 6029 struct spdk_io_channel *channel; 6030 struct spdk_bs_opts bs_opts; 6031 struct spdk_blob_opts opts; 6032 struct spdk_blob *blob; 6033 spdk_blob_id blobid, snapshotid0, snapshotid1, snapshotid2; 6034 6035 dev = init_dev(); 6036 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 6037 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 6038 6039 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 6040 poll_threads(); 6041 CU_ASSERT(g_bserrno == 0); 6042 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6043 bs = g_bs; 6044 6045 channel = spdk_bs_alloc_io_channel(bs); 6046 SPDK_CU_ASSERT_FATAL(channel != NULL); 6047 6048 /* 1. Create blob with 10 clusters */ 6049 ut_spdk_blob_opts_init(&opts); 6050 opts.num_clusters = 10; 6051 6052 blob = ut_blob_create_and_open(bs, &opts); 6053 blobid = spdk_blob_get_id(blob); 6054 6055 /* 2. Create snapshot0 */ 6056 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6057 poll_threads(); 6058 CU_ASSERT(g_bserrno == 0); 6059 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6060 snapshotid0 = g_blobid; 6061 6062 /* 3. Create snapshot1 */ 6063 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6064 poll_threads(); 6065 CU_ASSERT(g_bserrno == 0); 6066 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6067 snapshotid1 = g_blobid; 6068 6069 /* 4. Create snapshot2 */ 6070 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6071 poll_threads(); 6072 CU_ASSERT(g_bserrno == 0); 6073 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6074 snapshotid2 = g_blobid; 6075 6076 /* 5. Decouple blob */ 6077 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 6078 poll_threads(); 6079 CU_ASSERT(g_bserrno == 0); 6080 6081 /* 6. Decouple snapshot2. Make sure updating md of snapshot2 is possible */ 6082 spdk_bs_blob_decouple_parent(bs, channel, snapshotid2, blob_op_complete, NULL); 6083 poll_threads(); 6084 CU_ASSERT(g_bserrno == 0); 6085 6086 /* 7. Delete blob */ 6087 spdk_blob_close(blob, blob_op_complete, NULL); 6088 poll_threads(); 6089 CU_ASSERT(g_bserrno == 0); 6090 6091 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 6092 poll_threads(); 6093 CU_ASSERT(g_bserrno == 0); 6094 6095 /* 8. Delete snapshot2. 6096 * If md of snapshot 2 was updated, it should be possible to delete it */ 6097 spdk_bs_delete_blob(bs, snapshotid2, blob_op_complete, NULL); 6098 poll_threads(); 6099 CU_ASSERT(g_bserrno == 0); 6100 6101 /* Remove remaining blobs and unload bs */ 6102 spdk_bs_delete_blob(bs, snapshotid1, blob_op_complete, NULL); 6103 poll_threads(); 6104 CU_ASSERT(g_bserrno == 0); 6105 6106 spdk_bs_delete_blob(bs, snapshotid0, blob_op_complete, NULL); 6107 poll_threads(); 6108 CU_ASSERT(g_bserrno == 0); 6109 6110 spdk_bs_free_io_channel(channel); 6111 poll_threads(); 6112 6113 spdk_bs_unload(bs, bs_op_complete, NULL); 6114 poll_threads(); 6115 CU_ASSERT(g_bserrno == 0); 6116 6117 g_bs = NULL; 6118 } 6119 6120 static void 6121 blobstore_clean_power_failure(void) 6122 { 6123 struct spdk_blob_store *bs; 6124 struct spdk_blob *blob; 6125 struct spdk_power_failure_thresholds thresholds = {}; 6126 bool clean = false; 6127 struct spdk_bs_super_block *super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 6128 struct spdk_bs_super_block super_copy = {}; 6129 6130 thresholds.general_threshold = 1; 6131 while (!clean) { 6132 /* Create bs and blob */ 6133 suite_blob_setup(); 6134 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6135 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6136 bs = g_bs; 6137 blob = g_blob; 6138 6139 /* Super block should not change for rest of the UT, 6140 * save it and compare later. */ 6141 memcpy(&super_copy, super, sizeof(struct spdk_bs_super_block)); 6142 SPDK_CU_ASSERT_FATAL(super->clean == 0); 6143 SPDK_CU_ASSERT_FATAL(bs->clean == 0); 6144 6145 /* Force bs/super block in a clean state. 6146 * Along with marking blob dirty, to cause blob persist. */ 6147 blob->state = SPDK_BLOB_STATE_DIRTY; 6148 bs->clean = 1; 6149 super->clean = 1; 6150 super->crc = blob_md_page_calc_crc(super); 6151 6152 g_bserrno = -1; 6153 dev_set_power_failure_thresholds(thresholds); 6154 spdk_blob_sync_md(blob, blob_op_complete, NULL); 6155 poll_threads(); 6156 dev_reset_power_failure_event(); 6157 6158 if (g_bserrno == 0) { 6159 /* After successful md sync, both bs and super block 6160 * should be marked as not clean. */ 6161 SPDK_CU_ASSERT_FATAL(bs->clean == 0); 6162 SPDK_CU_ASSERT_FATAL(super->clean == 0); 6163 clean = true; 6164 } 6165 6166 /* Depending on the point of failure, super block was either updated or not. */ 6167 super_copy.clean = super->clean; 6168 super_copy.crc = blob_md_page_calc_crc(&super_copy); 6169 /* Compare that the values in super block remained unchanged. */ 6170 SPDK_CU_ASSERT_FATAL(!memcmp(&super_copy, super, sizeof(struct spdk_bs_super_block))); 6171 6172 /* Delete blob and unload bs */ 6173 suite_blob_cleanup(); 6174 6175 thresholds.general_threshold++; 6176 } 6177 } 6178 6179 static void 6180 blob_delete_snapshot_power_failure(void) 6181 { 6182 struct spdk_bs_dev *dev; 6183 struct spdk_blob_store *bs; 6184 struct spdk_blob_opts opts; 6185 struct spdk_blob *blob, *snapshot; 6186 struct spdk_power_failure_thresholds thresholds = {}; 6187 spdk_blob_id blobid, snapshotid; 6188 const void *value; 6189 size_t value_len; 6190 size_t count; 6191 spdk_blob_id ids[3] = {}; 6192 int rc; 6193 bool deleted = false; 6194 int delete_snapshot_bserrno = -1; 6195 6196 thresholds.general_threshold = 1; 6197 while (!deleted) { 6198 dev = init_dev(); 6199 6200 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 6201 poll_threads(); 6202 CU_ASSERT(g_bserrno == 0); 6203 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6204 bs = g_bs; 6205 6206 /* Create blob */ 6207 ut_spdk_blob_opts_init(&opts); 6208 opts.num_clusters = 10; 6209 6210 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 6211 poll_threads(); 6212 CU_ASSERT(g_bserrno == 0); 6213 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6214 blobid = g_blobid; 6215 6216 /* Create snapshot */ 6217 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6218 poll_threads(); 6219 CU_ASSERT(g_bserrno == 0); 6220 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6221 snapshotid = g_blobid; 6222 SPDK_CU_ASSERT_FATAL(spdk_bit_pool_is_allocated(bs->used_clusters, 1)); 6223 SPDK_CU_ASSERT_FATAL(!spdk_bit_pool_is_allocated(bs->used_clusters, 11)); 6224 6225 dev_set_power_failure_thresholds(thresholds); 6226 6227 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 6228 poll_threads(); 6229 delete_snapshot_bserrno = g_bserrno; 6230 6231 /* Do not shut down cleanly. Assumption is that after snapshot deletion 6232 * reports success, changes to both blobs should already persisted. */ 6233 dev_reset_power_failure_event(); 6234 ut_bs_dirty_load(&bs, NULL); 6235 6236 SPDK_CU_ASSERT_FATAL(spdk_bit_pool_is_allocated(bs->used_clusters, 1)); 6237 SPDK_CU_ASSERT_FATAL(!spdk_bit_pool_is_allocated(bs->used_clusters, 11)); 6238 6239 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 6240 poll_threads(); 6241 CU_ASSERT(g_bserrno == 0); 6242 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6243 blob = g_blob; 6244 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true); 6245 6246 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 6247 poll_threads(); 6248 6249 if (g_bserrno == 0) { 6250 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6251 snapshot = g_blob; 6252 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 6253 count = SPDK_COUNTOF(ids); 6254 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 6255 CU_ASSERT(rc == 0); 6256 CU_ASSERT(count == 1); 6257 CU_ASSERT(ids[0] == blobid); 6258 rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_PENDING_REMOVAL, &value, &value_len); 6259 CU_ASSERT(rc != 0); 6260 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(snapshot) == false); 6261 6262 spdk_blob_close(snapshot, blob_op_complete, NULL); 6263 poll_threads(); 6264 CU_ASSERT(g_bserrno == 0); 6265 } else { 6266 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 6267 /* Snapshot might have been left in unrecoverable state, so it does not open. 6268 * Yet delete might perform further changes to the clone after that. 6269 * This UT should test until snapshot is deleted and delete call succeeds. */ 6270 if (delete_snapshot_bserrno == 0) { 6271 deleted = true; 6272 } 6273 } 6274 6275 spdk_blob_close(blob, blob_op_complete, NULL); 6276 poll_threads(); 6277 CU_ASSERT(g_bserrno == 0); 6278 6279 spdk_bs_unload(bs, bs_op_complete, NULL); 6280 poll_threads(); 6281 CU_ASSERT(g_bserrno == 0); 6282 6283 thresholds.general_threshold++; 6284 } 6285 } 6286 6287 static void 6288 blob_create_snapshot_power_failure(void) 6289 { 6290 struct spdk_blob_store *bs = g_bs; 6291 struct spdk_bs_dev *dev; 6292 struct spdk_blob_opts opts; 6293 struct spdk_blob *blob, *snapshot; 6294 struct spdk_power_failure_thresholds thresholds = {}; 6295 spdk_blob_id blobid, snapshotid; 6296 const void *value; 6297 size_t value_len; 6298 size_t count; 6299 spdk_blob_id ids[3] = {}; 6300 int rc; 6301 bool created = false; 6302 int create_snapshot_bserrno = -1; 6303 6304 thresholds.general_threshold = 1; 6305 while (!created) { 6306 dev = init_dev(); 6307 6308 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 6309 poll_threads(); 6310 CU_ASSERT(g_bserrno == 0); 6311 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 6312 bs = g_bs; 6313 6314 /* Create blob */ 6315 ut_spdk_blob_opts_init(&opts); 6316 opts.num_clusters = 10; 6317 6318 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 6319 poll_threads(); 6320 CU_ASSERT(g_bserrno == 0); 6321 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 6322 blobid = g_blobid; 6323 SPDK_CU_ASSERT_FATAL(spdk_bit_pool_is_allocated(bs->used_clusters, 1)); 6324 SPDK_CU_ASSERT_FATAL(!spdk_bit_pool_is_allocated(bs->used_clusters, 11)); 6325 6326 dev_set_power_failure_thresholds(thresholds); 6327 6328 /* Create snapshot */ 6329 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 6330 poll_threads(); 6331 create_snapshot_bserrno = g_bserrno; 6332 snapshotid = g_blobid; 6333 SPDK_CU_ASSERT_FATAL(spdk_bit_pool_is_allocated(bs->used_clusters, 1)); 6334 SPDK_CU_ASSERT_FATAL(!spdk_bit_pool_is_allocated(bs->used_clusters, 11)); 6335 6336 /* Do not shut down cleanly. Assumption is that after create snapshot 6337 * reports success, both blobs should be power-fail safe. */ 6338 dev_reset_power_failure_event(); 6339 ut_bs_dirty_load(&bs, NULL); 6340 6341 SPDK_CU_ASSERT_FATAL(spdk_bit_pool_is_allocated(bs->used_clusters, 1)); 6342 SPDK_CU_ASSERT_FATAL(!spdk_bit_pool_is_allocated(bs->used_clusters, 11)); 6343 6344 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 6345 poll_threads(); 6346 CU_ASSERT(g_bserrno == 0); 6347 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6348 blob = g_blob; 6349 6350 if (snapshotid != SPDK_BLOBID_INVALID) { 6351 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 6352 poll_threads(); 6353 } 6354 6355 if ((snapshotid != SPDK_BLOBID_INVALID) && (g_bserrno == 0)) { 6356 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 6357 snapshot = g_blob; 6358 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == true); 6359 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(snapshot) == false); 6360 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 6361 count = SPDK_COUNTOF(ids); 6362 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 6363 CU_ASSERT(rc == 0); 6364 CU_ASSERT(count == 1); 6365 CU_ASSERT(ids[0] == blobid); 6366 rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_IN_PROGRESS, &value, &value_len); 6367 CU_ASSERT(rc != 0); 6368 6369 spdk_blob_close(snapshot, blob_op_complete, NULL); 6370 poll_threads(); 6371 CU_ASSERT(g_bserrno == 0); 6372 if (create_snapshot_bserrno == 0) { 6373 created = true; 6374 } 6375 } else { 6376 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 6377 SPDK_CU_ASSERT_FATAL(spdk_blob_is_thin_provisioned(blob) == false); 6378 } 6379 6380 spdk_blob_close(blob, blob_op_complete, NULL); 6381 poll_threads(); 6382 CU_ASSERT(g_bserrno == 0); 6383 6384 spdk_bs_unload(bs, bs_op_complete, NULL); 6385 poll_threads(); 6386 CU_ASSERT(g_bserrno == 0); 6387 6388 thresholds.general_threshold++; 6389 } 6390 } 6391 6392 static void 6393 test_io_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6394 { 6395 uint8_t payload_ff[64 * 512]; 6396 uint8_t payload_aa[64 * 512]; 6397 uint8_t payload_00[64 * 512]; 6398 uint8_t *cluster0, *cluster1; 6399 6400 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6401 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6402 memset(payload_00, 0x00, sizeof(payload_00)); 6403 6404 /* Try to perform I/O with io unit = 512 */ 6405 spdk_blob_io_write(blob, channel, payload_ff, 0, 1, blob_op_complete, NULL); 6406 poll_threads(); 6407 CU_ASSERT(g_bserrno == 0); 6408 6409 /* If thin provisioned is set cluster should be allocated now */ 6410 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 6411 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6412 6413 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 6414 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 6415 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6416 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6417 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 6418 6419 /* Verify write with offset on first page */ 6420 spdk_blob_io_write(blob, channel, payload_ff, 2, 1, blob_op_complete, NULL); 6421 poll_threads(); 6422 CU_ASSERT(g_bserrno == 0); 6423 6424 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6425 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6426 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6427 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6428 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6429 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 6430 6431 /* Verify write with offset on first page */ 6432 spdk_blob_io_write(blob, channel, payload_ff, 4, 4, blob_op_complete, NULL); 6433 poll_threads(); 6434 6435 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6436 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6437 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6438 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6439 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6440 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 6441 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 6442 6443 /* Verify write with offset on second page */ 6444 spdk_blob_io_write(blob, channel, payload_ff, 8, 4, blob_op_complete, NULL); 6445 poll_threads(); 6446 6447 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 6448 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6449 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6450 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6451 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6452 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 6453 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6454 6455 /* Verify write across multiple pages */ 6456 spdk_blob_io_write(blob, channel, payload_aa, 4, 8, blob_op_complete, NULL); 6457 poll_threads(); 6458 6459 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 6460 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6461 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6462 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6463 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6464 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6465 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6466 6467 /* Verify write across multiple clusters */ 6468 spdk_blob_io_write(blob, channel, payload_ff, 28, 8, blob_op_complete, NULL); 6469 poll_threads(); 6470 6471 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6472 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6473 6474 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6475 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6476 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6477 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6478 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6479 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6480 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6481 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6482 6483 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6484 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 6485 6486 /* Verify write to second cluster */ 6487 spdk_blob_io_write(blob, channel, payload_ff, 32 + 12, 2, blob_op_complete, NULL); 6488 poll_threads(); 6489 6490 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6491 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6492 6493 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6494 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 6495 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6496 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6497 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6498 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6499 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6500 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6501 6502 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6503 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 6504 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 6505 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 6506 } 6507 6508 static void 6509 test_io_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6510 { 6511 uint8_t payload_read[64 * 512]; 6512 uint8_t payload_ff[64 * 512]; 6513 uint8_t payload_aa[64 * 512]; 6514 uint8_t payload_00[64 * 512]; 6515 6516 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6517 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6518 memset(payload_00, 0x00, sizeof(payload_00)); 6519 6520 /* Read only first io unit */ 6521 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6522 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6523 * payload_read: F000 0000 | 0000 0000 ... */ 6524 memset(payload_read, 0x00, sizeof(payload_read)); 6525 spdk_blob_io_read(blob, channel, payload_read, 0, 1, blob_op_complete, NULL); 6526 poll_threads(); 6527 CU_ASSERT(g_bserrno == 0); 6528 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6529 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 6530 6531 /* Read four io_units starting from offset = 2 6532 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6533 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6534 * payload_read: F0AA 0000 | 0000 0000 ... */ 6535 6536 memset(payload_read, 0x00, sizeof(payload_read)); 6537 spdk_blob_io_read(blob, channel, payload_read, 2, 4, blob_op_complete, NULL); 6538 poll_threads(); 6539 CU_ASSERT(g_bserrno == 0); 6540 6541 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6542 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6543 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 6544 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 6545 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6546 6547 /* Read eight io_units across multiple pages 6548 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6549 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6550 * payload_read: AAAA AAAA | 0000 0000 ... */ 6551 memset(payload_read, 0x00, sizeof(payload_read)); 6552 spdk_blob_io_read(blob, channel, payload_read, 4, 8, blob_op_complete, NULL); 6553 poll_threads(); 6554 CU_ASSERT(g_bserrno == 0); 6555 6556 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 6557 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6558 6559 /* Read eight io_units across multiple clusters 6560 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 6561 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6562 * payload_read: FFFF FFFF | 0000 0000 ... */ 6563 memset(payload_read, 0x00, sizeof(payload_read)); 6564 spdk_blob_io_read(blob, channel, payload_read, 28, 8, blob_op_complete, NULL); 6565 poll_threads(); 6566 CU_ASSERT(g_bserrno == 0); 6567 6568 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 6569 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6570 6571 /* Read four io_units from second cluster 6572 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6573 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 6574 * payload_read: 00FF 0000 | 0000 0000 ... */ 6575 memset(payload_read, 0x00, sizeof(payload_read)); 6576 spdk_blob_io_read(blob, channel, payload_read, 32 + 10, 4, blob_op_complete, NULL); 6577 poll_threads(); 6578 CU_ASSERT(g_bserrno == 0); 6579 6580 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 6581 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 6582 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6583 6584 /* Read second cluster 6585 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6586 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 6587 * payload_read: FFFF 0000 | 0000 FF00 ... */ 6588 memset(payload_read, 0x00, sizeof(payload_read)); 6589 spdk_blob_io_read(blob, channel, payload_read, 32, 32, blob_op_complete, NULL); 6590 poll_threads(); 6591 CU_ASSERT(g_bserrno == 0); 6592 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 6593 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 6594 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 6595 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 6596 6597 /* Read whole two clusters 6598 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6599 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 6600 memset(payload_read, 0x00, sizeof(payload_read)); 6601 spdk_blob_io_read(blob, channel, payload_read, 0, 64, blob_op_complete, NULL); 6602 poll_threads(); 6603 CU_ASSERT(g_bserrno == 0); 6604 6605 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6606 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6607 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 6608 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 6609 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 6610 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 6611 6612 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 6613 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 6614 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 6615 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 6616 } 6617 6618 6619 static void 6620 test_io_unmap(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6621 { 6622 uint8_t payload_ff[64 * 512]; 6623 uint8_t payload_aa[64 * 512]; 6624 uint8_t payload_00[64 * 512]; 6625 uint8_t *cluster0, *cluster1; 6626 6627 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6628 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6629 memset(payload_00, 0x00, sizeof(payload_00)); 6630 6631 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6632 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6633 6634 /* Unmap */ 6635 spdk_blob_io_unmap(blob, channel, 0, 64, blob_op_complete, NULL); 6636 poll_threads(); 6637 6638 CU_ASSERT(g_bserrno == 0); 6639 6640 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 6641 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 6642 } 6643 6644 static void 6645 test_io_zeroes(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel) 6646 { 6647 uint8_t payload_ff[64 * 512]; 6648 uint8_t payload_aa[64 * 512]; 6649 uint8_t payload_00[64 * 512]; 6650 uint8_t *cluster0, *cluster1; 6651 6652 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6653 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6654 memset(payload_00, 0x00, sizeof(payload_00)); 6655 6656 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6657 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6658 6659 /* Write zeroes */ 6660 spdk_blob_io_write_zeroes(blob, channel, 0, 64, blob_op_complete, NULL); 6661 poll_threads(); 6662 6663 CU_ASSERT(g_bserrno == 0); 6664 6665 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_00, 32 * 512) == 0); 6666 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_00, 32 * 512) == 0); 6667 } 6668 6669 static inline void 6670 test_blob_io_writev(struct spdk_blob *blob, struct spdk_io_channel *channel, 6671 struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length, 6672 spdk_blob_op_complete cb_fn, void *cb_arg, struct spdk_blob_ext_io_opts *io_opts) 6673 { 6674 if (io_opts) { 6675 g_dev_writev_ext_called = false; 6676 memset(&g_blob_ext_io_opts, 0, sizeof(g_blob_ext_io_opts)); 6677 spdk_blob_io_writev_ext(blob, channel, iov, iovcnt, offset, length, blob_op_complete, NULL, 6678 io_opts); 6679 } else { 6680 spdk_blob_io_writev(blob, channel, iov, iovcnt, offset, length, blob_op_complete, NULL); 6681 } 6682 poll_threads(); 6683 CU_ASSERT(g_bserrno == 0); 6684 if (io_opts) { 6685 CU_ASSERT(g_dev_writev_ext_called); 6686 CU_ASSERT(memcmp(io_opts, &g_blob_ext_io_opts, sizeof(g_blob_ext_io_opts)) == 0); 6687 } 6688 } 6689 6690 static void 6691 test_iov_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel, 6692 bool ext_api) 6693 { 6694 uint8_t payload_ff[64 * 512]; 6695 uint8_t payload_aa[64 * 512]; 6696 uint8_t payload_00[64 * 512]; 6697 uint8_t *cluster0, *cluster1; 6698 struct iovec iov[4]; 6699 struct spdk_blob_ext_io_opts ext_opts = { 6700 .memory_domain = (struct spdk_memory_domain *)0xfeedbeef, 6701 .memory_domain_ctx = (void *)0xf00df00d, 6702 .size = sizeof(struct spdk_blob_ext_io_opts), 6703 .user_ctx = (void *)123, 6704 }; 6705 6706 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6707 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6708 memset(payload_00, 0x00, sizeof(payload_00)); 6709 6710 /* Try to perform I/O with io unit = 512 */ 6711 iov[0].iov_base = payload_ff; 6712 iov[0].iov_len = 1 * 512; 6713 6714 test_blob_io_writev(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL, 6715 ext_api ? &ext_opts : NULL); 6716 6717 /* If thin provisioned is set cluster should be allocated now */ 6718 SPDK_CU_ASSERT_FATAL(blob->active.clusters[0] != 0); 6719 cluster0 = &g_dev_buffer[blob->active.clusters[0] * dev->blocklen]; 6720 6721 /* Each character 0-F symbolizes single io_unit containing 512 bytes block filled with that character. 6722 * Each page is separated by |. Whole block [...] symbolizes one cluster (containing 4 pages). */ 6723 /* cluster0: [ F000 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6724 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6725 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 31 * 512) == 0); 6726 6727 /* Verify write with offset on first page */ 6728 iov[0].iov_base = payload_ff; 6729 iov[0].iov_len = 1 * 512; 6730 6731 test_blob_io_writev(blob, channel, iov, 1, 2, 1, blob_op_complete, NULL, 6732 ext_api ? &ext_opts : NULL); 6733 6734 /* cluster0: [ F0F0 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6735 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6736 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6737 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6738 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6739 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_00, 28 * 512) == 0); 6740 6741 /* Verify write with offset on first page */ 6742 iov[0].iov_base = payload_ff; 6743 iov[0].iov_len = 4 * 512; 6744 spdk_blob_io_writev(blob, channel, iov, 1, 4, 4, blob_op_complete, NULL); 6745 poll_threads(); 6746 6747 /* cluster0: [ F0F0 FFFF | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6748 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6749 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6750 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6751 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6752 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 4 * 512) == 0); 6753 CU_ASSERT(memcmp(cluster0 + 8 * 512, payload_00, 24 * 512) == 0); 6754 6755 /* Verify write with offset on second page */ 6756 iov[0].iov_base = payload_ff; 6757 iov[0].iov_len = 4 * 512; 6758 spdk_blob_io_writev(blob, channel, iov, 1, 8, 4, blob_op_complete, NULL); 6759 poll_threads(); 6760 6761 /* cluster0: [ F0F0 FFFF | FFFF 0000 | 0000 0000 | 0000 0000 ] */ 6762 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6763 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6764 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6765 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6766 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_ff, 8 * 512) == 0); 6767 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6768 6769 /* Verify write across multiple pages */ 6770 iov[0].iov_base = payload_aa; 6771 iov[0].iov_len = 8 * 512; 6772 6773 test_blob_io_writev(blob, channel, iov, 1, 4, 8, blob_op_complete, NULL, 6774 ext_api ? &ext_opts : NULL); 6775 6776 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 0000 ] */ 6777 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6778 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6779 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6780 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6781 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6782 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 20 * 512) == 0); 6783 6784 /* Verify write across multiple clusters */ 6785 6786 iov[0].iov_base = payload_ff; 6787 iov[0].iov_len = 8 * 512; 6788 6789 test_blob_io_writev(blob, channel, iov, 1, 28, 8, blob_op_complete, NULL, 6790 ext_api ? &ext_opts : NULL); 6791 6792 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6793 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6794 6795 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6796 * cluster1: [ FFFF 0000 | 0000 0000 | 0000 0000 | 0000 0000 ] */ 6797 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6798 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6799 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6800 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6801 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6802 CU_ASSERT(memcmp(cluster0 + 12 * 512, payload_00, 16 * 512) == 0); 6803 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6804 6805 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6806 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 28 * 512) == 0); 6807 6808 /* Verify write to second cluster */ 6809 6810 iov[0].iov_base = payload_ff; 6811 iov[0].iov_len = 2 * 512; 6812 6813 test_blob_io_writev(blob, channel, iov, 1, 32 + 12, 2, blob_op_complete, NULL, 6814 ext_api ? &ext_opts : NULL); 6815 6816 SPDK_CU_ASSERT_FATAL(blob->active.clusters[1] != 0); 6817 cluster1 = &g_dev_buffer[blob->active.clusters[1] * dev->blocklen]; 6818 6819 /* cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6820 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] */ 6821 CU_ASSERT(memcmp(cluster0 + 0 * 512, payload_ff, 512) == 0); 6822 CU_ASSERT(memcmp(cluster0 + 1 * 512, payload_00, 512) == 0); 6823 CU_ASSERT(memcmp(cluster0 + 2 * 512, payload_ff, 512) == 0); 6824 CU_ASSERT(memcmp(cluster0 + 3 * 512, payload_00, 512) == 0); 6825 CU_ASSERT(memcmp(cluster0 + 4 * 512, payload_aa, 8 * 512) == 0); 6826 CU_ASSERT(memcmp(cluster0 + 28 * 512, payload_ff, 4 * 512) == 0); 6827 6828 CU_ASSERT(memcmp(cluster1 + 0 * 512, payload_ff, 4 * 512) == 0); 6829 CU_ASSERT(memcmp(cluster1 + 4 * 512, payload_00, 8 * 512) == 0); 6830 CU_ASSERT(memcmp(cluster1 + 12 * 512, payload_ff, 2 * 512) == 0); 6831 CU_ASSERT(memcmp(cluster1 + 14 * 512, payload_00, 18 * 512) == 0); 6832 } 6833 6834 static inline void 6835 test_blob_io_readv(struct spdk_blob *blob, struct spdk_io_channel *channel, 6836 struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length, 6837 spdk_blob_op_complete cb_fn, void *cb_arg, struct spdk_blob_ext_io_opts *io_opts) 6838 { 6839 if (io_opts) { 6840 g_dev_readv_ext_called = false; 6841 memset(&g_blob_ext_io_opts, 0, sizeof(g_blob_ext_io_opts)); 6842 spdk_blob_io_readv_ext(blob, channel, iov, iovcnt, offset, length, blob_op_complete, NULL, io_opts); 6843 } else { 6844 spdk_blob_io_readv(blob, channel, iov, iovcnt, offset, length, blob_op_complete, NULL); 6845 } 6846 poll_threads(); 6847 CU_ASSERT(g_bserrno == 0); 6848 if (io_opts) { 6849 CU_ASSERT(g_dev_readv_ext_called); 6850 CU_ASSERT(memcmp(io_opts, &g_blob_ext_io_opts, sizeof(g_blob_ext_io_opts)) == 0); 6851 } 6852 } 6853 6854 static void 6855 test_iov_read(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel, 6856 bool ext_api) 6857 { 6858 uint8_t payload_read[64 * 512]; 6859 uint8_t payload_ff[64 * 512]; 6860 uint8_t payload_aa[64 * 512]; 6861 uint8_t payload_00[64 * 512]; 6862 struct iovec iov[4]; 6863 struct spdk_blob_ext_io_opts ext_opts = { 6864 .memory_domain = (struct spdk_memory_domain *)0xfeedbeef, 6865 .memory_domain_ctx = (void *)0xf00df00d, 6866 .size = sizeof(struct spdk_blob_ext_io_opts), 6867 .user_ctx = (void *)123, 6868 }; 6869 6870 memset(payload_ff, 0xFF, sizeof(payload_ff)); 6871 memset(payload_aa, 0xAA, sizeof(payload_aa)); 6872 memset(payload_00, 0x00, sizeof(payload_00)); 6873 6874 /* Read only first io unit */ 6875 /* cluster0: [ (F)0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6876 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6877 * payload_read: F000 0000 | 0000 0000 ... */ 6878 memset(payload_read, 0x00, sizeof(payload_read)); 6879 iov[0].iov_base = payload_read; 6880 iov[0].iov_len = 1 * 512; 6881 6882 test_blob_io_readv(blob, channel, iov, 1, 0, 1, blob_op_complete, NULL, ext_api ? &ext_opts : NULL); 6883 6884 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6885 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 31 * 512) == 0); 6886 6887 /* Read four io_units starting from offset = 2 6888 * cluster0: [ F0(F0 AA)AA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6889 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6890 * payload_read: F0AA 0000 | 0000 0000 ... */ 6891 6892 memset(payload_read, 0x00, sizeof(payload_read)); 6893 iov[0].iov_base = payload_read; 6894 iov[0].iov_len = 4 * 512; 6895 6896 test_blob_io_readv(blob, channel, iov, 1, 2, 4, blob_op_complete, NULL, ext_api ? &ext_opts : NULL); 6897 6898 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6899 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6900 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_aa, 512) == 0); 6901 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_aa, 512) == 0); 6902 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6903 6904 /* Read eight io_units across multiple pages 6905 * cluster0: [ F0F0 (AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6906 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6907 * payload_read: AAAA AAAA | 0000 0000 ... */ 6908 memset(payload_read, 0x00, sizeof(payload_read)); 6909 iov[0].iov_base = payload_read; 6910 iov[0].iov_len = 4 * 512; 6911 iov[1].iov_base = payload_read + 4 * 512; 6912 iov[1].iov_len = 4 * 512; 6913 6914 test_blob_io_readv(blob, channel, iov, 2, 4, 8, blob_op_complete, NULL, ext_api ? &ext_opts : NULL); 6915 6916 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_aa, 8 * 512) == 0); 6917 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6918 6919 /* Read eight io_units across multiple clusters 6920 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 (FFFF ] 6921 * cluster1: [ FFFF) 0000 | 0000 FF00 | 0000 0000 | 0000 0000 ] 6922 * payload_read: FFFF FFFF | 0000 0000 ... */ 6923 memset(payload_read, 0x00, sizeof(payload_read)); 6924 iov[0].iov_base = payload_read; 6925 iov[0].iov_len = 2 * 512; 6926 iov[1].iov_base = payload_read + 2 * 512; 6927 iov[1].iov_len = 2 * 512; 6928 iov[2].iov_base = payload_read + 4 * 512; 6929 iov[2].iov_len = 2 * 512; 6930 iov[3].iov_base = payload_read + 6 * 512; 6931 iov[3].iov_len = 2 * 512; 6932 6933 test_blob_io_readv(blob, channel, iov, 4, 28, 8, blob_op_complete, NULL, 6934 ext_api ? &ext_opts : NULL); 6935 6936 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 8 * 512) == 0); 6937 CU_ASSERT(memcmp(payload_read + 8 * 512, payload_00, 24 * 512) == 0); 6938 6939 /* Read four io_units from second cluster 6940 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6941 * cluster1: [ FFFF 0000 | 00(00 FF)00 | 0000 0000 | 0000 0000 ] 6942 * payload_read: 00FF 0000 | 0000 0000 ... */ 6943 memset(payload_read, 0x00, sizeof(payload_read)); 6944 iov[0].iov_base = payload_read; 6945 iov[0].iov_len = 1 * 512; 6946 iov[1].iov_base = payload_read + 1 * 512; 6947 iov[1].iov_len = 3 * 512; 6948 6949 test_blob_io_readv(blob, channel, iov, 2, 32 + 10, 4, blob_op_complete, NULL, 6950 ext_api ? &ext_opts : NULL); 6951 6952 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_00, 2 * 512) == 0); 6953 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 2 * 512) == 0); 6954 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 28 * 512) == 0); 6955 6956 /* Read second cluster 6957 * cluster0: [ F0F0 AAAA | AAAA 0000 | 0000 0000 | 0000 FFFF ] 6958 * cluster1: [ (FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] 6959 * payload_read: FFFF 0000 | 0000 FF00 ... */ 6960 memset(payload_read, 0x00, sizeof(payload_read)); 6961 iov[0].iov_base = payload_read; 6962 iov[0].iov_len = 1 * 512; 6963 iov[1].iov_base = payload_read + 1 * 512; 6964 iov[1].iov_len = 2 * 512; 6965 iov[2].iov_base = payload_read + 3 * 512; 6966 iov[2].iov_len = 4 * 512; 6967 iov[3].iov_base = payload_read + 7 * 512; 6968 iov[3].iov_len = 25 * 512; 6969 6970 test_blob_io_readv(blob, channel, iov, 4, 32, 32, blob_op_complete, NULL, 6971 ext_api ? &ext_opts : NULL); 6972 6973 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 4 * 512) == 0); 6974 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_00, 8 * 512) == 0); 6975 CU_ASSERT(memcmp(payload_read + 12 * 512, payload_ff, 2 * 512) == 0); 6976 CU_ASSERT(memcmp(payload_read + 14 * 512, payload_00, 18 * 512) == 0); 6977 6978 /* Read whole two clusters 6979 * cluster0: [ (F0F0 AAAA | AAAA) 0000 | 0000 0000 | 0000 FFFF ] 6980 * cluster1: [ FFFF 0000 | 0000 FF00 | 0000 0000 | 0000 0000) ] */ 6981 memset(payload_read, 0x00, sizeof(payload_read)); 6982 iov[0].iov_base = payload_read; 6983 iov[0].iov_len = 1 * 512; 6984 iov[1].iov_base = payload_read + 1 * 512; 6985 iov[1].iov_len = 8 * 512; 6986 iov[2].iov_base = payload_read + 9 * 512; 6987 iov[2].iov_len = 16 * 512; 6988 iov[3].iov_base = payload_read + 25 * 512; 6989 iov[3].iov_len = 39 * 512; 6990 6991 test_blob_io_readv(blob, channel, iov, 4, 0, 64, blob_op_complete, NULL, 6992 ext_api ? &ext_opts : NULL); 6993 6994 CU_ASSERT(memcmp(payload_read + 0 * 512, payload_ff, 512) == 0); 6995 CU_ASSERT(memcmp(payload_read + 1 * 512, payload_00, 512) == 0); 6996 CU_ASSERT(memcmp(payload_read + 2 * 512, payload_ff, 512) == 0); 6997 CU_ASSERT(memcmp(payload_read + 3 * 512, payload_00, 512) == 0); 6998 CU_ASSERT(memcmp(payload_read + 4 * 512, payload_aa, 8 * 512) == 0); 6999 CU_ASSERT(memcmp(payload_read + 28 * 512, payload_ff, 4 * 512) == 0); 7000 7001 CU_ASSERT(memcmp(payload_read + (32 + 0) * 512, payload_ff, 4 * 512) == 0); 7002 CU_ASSERT(memcmp(payload_read + (32 + 4) * 512, payload_00, 8 * 512) == 0); 7003 CU_ASSERT(memcmp(payload_read + (32 + 12) * 512, payload_ff, 2 * 512) == 0); 7004 CU_ASSERT(memcmp(payload_read + (32 + 14) * 512, payload_00, 18 * 512) == 0); 7005 } 7006 7007 static void 7008 blob_io_unit(void) 7009 { 7010 struct spdk_bs_opts bsopts; 7011 struct spdk_blob_opts opts; 7012 struct spdk_blob_store *bs; 7013 struct spdk_bs_dev *dev; 7014 struct spdk_blob *blob, *snapshot, *clone; 7015 spdk_blob_id blobid; 7016 struct spdk_io_channel *channel; 7017 7018 /* Create dev with 512 bytes io unit size */ 7019 7020 spdk_bs_opts_init(&bsopts, sizeof(bsopts)); 7021 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 7022 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 7023 7024 /* Try to initialize a new blob store with unsupported io_unit */ 7025 dev = init_dev(); 7026 dev->blocklen = 512; 7027 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 7028 7029 /* Initialize a new blob store */ 7030 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 7031 poll_threads(); 7032 CU_ASSERT(g_bserrno == 0); 7033 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7034 bs = g_bs; 7035 7036 CU_ASSERT(spdk_bs_get_io_unit_size(bs) == 512); 7037 channel = spdk_bs_alloc_io_channel(bs); 7038 7039 /* Create thick provisioned blob */ 7040 ut_spdk_blob_opts_init(&opts); 7041 opts.thin_provision = false; 7042 opts.num_clusters = 32; 7043 7044 blob = ut_blob_create_and_open(bs, &opts); 7045 blobid = spdk_blob_get_id(blob); 7046 7047 test_io_write(dev, blob, channel); 7048 test_io_read(dev, blob, channel); 7049 test_io_zeroes(dev, blob, channel); 7050 7051 test_iov_write(dev, blob, channel, false); 7052 test_iov_read(dev, blob, channel, false); 7053 test_io_zeroes(dev, blob, channel); 7054 7055 test_iov_write(dev, blob, channel, true); 7056 test_iov_read(dev, blob, channel, true); 7057 7058 test_io_unmap(dev, blob, channel); 7059 7060 spdk_blob_close(blob, blob_op_complete, NULL); 7061 poll_threads(); 7062 CU_ASSERT(g_bserrno == 0); 7063 blob = NULL; 7064 g_blob = NULL; 7065 7066 /* Create thin provisioned blob */ 7067 7068 ut_spdk_blob_opts_init(&opts); 7069 opts.thin_provision = true; 7070 opts.num_clusters = 32; 7071 7072 blob = ut_blob_create_and_open(bs, &opts); 7073 blobid = spdk_blob_get_id(blob); 7074 7075 test_io_write(dev, blob, channel); 7076 test_io_read(dev, blob, channel); 7077 test_io_zeroes(dev, blob, channel); 7078 7079 test_iov_write(dev, blob, channel, false); 7080 test_iov_read(dev, blob, channel, false); 7081 test_io_zeroes(dev, blob, channel); 7082 7083 test_iov_write(dev, blob, channel, true); 7084 test_iov_read(dev, blob, channel, true); 7085 7086 /* Create snapshot */ 7087 7088 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 7089 poll_threads(); 7090 CU_ASSERT(g_bserrno == 0); 7091 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7092 blobid = g_blobid; 7093 7094 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7095 poll_threads(); 7096 CU_ASSERT(g_bserrno == 0); 7097 CU_ASSERT(g_blob != NULL); 7098 snapshot = g_blob; 7099 7100 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 7101 poll_threads(); 7102 CU_ASSERT(g_bserrno == 0); 7103 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7104 blobid = g_blobid; 7105 7106 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7107 poll_threads(); 7108 CU_ASSERT(g_bserrno == 0); 7109 CU_ASSERT(g_blob != NULL); 7110 clone = g_blob; 7111 7112 test_io_read(dev, blob, channel); 7113 test_io_read(dev, snapshot, channel); 7114 test_io_read(dev, clone, channel); 7115 7116 test_iov_read(dev, blob, channel, false); 7117 test_iov_read(dev, snapshot, channel, false); 7118 test_iov_read(dev, clone, channel, false); 7119 7120 test_iov_read(dev, blob, channel, true); 7121 test_iov_read(dev, snapshot, channel, true); 7122 test_iov_read(dev, clone, channel, true); 7123 7124 /* Inflate clone */ 7125 7126 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 7127 poll_threads(); 7128 7129 CU_ASSERT(g_bserrno == 0); 7130 7131 test_io_read(dev, clone, channel); 7132 7133 test_io_unmap(dev, clone, channel); 7134 7135 test_iov_write(dev, clone, channel, false); 7136 test_iov_read(dev, clone, channel, false); 7137 test_io_unmap(dev, clone, channel); 7138 7139 test_iov_write(dev, clone, channel, true); 7140 test_iov_read(dev, clone, channel, true); 7141 7142 spdk_blob_close(blob, blob_op_complete, NULL); 7143 spdk_blob_close(snapshot, blob_op_complete, NULL); 7144 spdk_blob_close(clone, blob_op_complete, NULL); 7145 poll_threads(); 7146 CU_ASSERT(g_bserrno == 0); 7147 blob = NULL; 7148 g_blob = NULL; 7149 7150 spdk_bs_free_io_channel(channel); 7151 poll_threads(); 7152 7153 /* Unload the blob store */ 7154 spdk_bs_unload(bs, bs_op_complete, NULL); 7155 poll_threads(); 7156 CU_ASSERT(g_bserrno == 0); 7157 g_bs = NULL; 7158 g_blob = NULL; 7159 g_blobid = 0; 7160 } 7161 7162 static void 7163 blob_io_unit_compatibility(void) 7164 { 7165 struct spdk_bs_opts bsopts; 7166 struct spdk_blob_store *bs; 7167 struct spdk_bs_dev *dev; 7168 struct spdk_bs_super_block *super; 7169 7170 /* Create dev with 512 bytes io unit size */ 7171 7172 spdk_bs_opts_init(&bsopts, sizeof(bsopts)); 7173 bsopts.cluster_sz = SPDK_BS_PAGE_SIZE * 4; /* 8 * 4 = 32 io_unit */ 7174 snprintf(bsopts.bstype.bstype, sizeof(bsopts.bstype.bstype), "TESTTYPE"); 7175 7176 /* Try to initialize a new blob store with unsupported io_unit */ 7177 dev = init_dev(); 7178 dev->blocklen = 512; 7179 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 7180 7181 /* Initialize a new blob store */ 7182 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 7183 poll_threads(); 7184 CU_ASSERT(g_bserrno == 0); 7185 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7186 bs = g_bs; 7187 7188 CU_ASSERT(spdk_bs_get_io_unit_size(bs) == 512); 7189 7190 /* Unload the blob store */ 7191 spdk_bs_unload(bs, bs_op_complete, NULL); 7192 poll_threads(); 7193 CU_ASSERT(g_bserrno == 0); 7194 7195 /* Modify super block to behave like older version. 7196 * Check if loaded io unit size equals SPDK_BS_PAGE_SIZE */ 7197 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 7198 super->io_unit_size = 0; 7199 super->crc = blob_md_page_calc_crc(super); 7200 7201 dev = init_dev(); 7202 dev->blocklen = 512; 7203 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 7204 7205 spdk_bs_load(dev, &bsopts, bs_op_with_handle_complete, NULL); 7206 poll_threads(); 7207 CU_ASSERT(g_bserrno == 0); 7208 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7209 bs = g_bs; 7210 7211 CU_ASSERT(spdk_bs_get_io_unit_size(bs) == SPDK_BS_PAGE_SIZE); 7212 7213 /* Unload the blob store */ 7214 spdk_bs_unload(bs, bs_op_complete, NULL); 7215 poll_threads(); 7216 CU_ASSERT(g_bserrno == 0); 7217 7218 g_bs = NULL; 7219 g_blob = NULL; 7220 g_blobid = 0; 7221 } 7222 7223 static void 7224 first_sync_complete(void *cb_arg, int bserrno) 7225 { 7226 struct spdk_blob *blob = cb_arg; 7227 int rc; 7228 7229 CU_ASSERT(bserrno == 0); 7230 rc = spdk_blob_set_xattr(blob, "sync", "second", strlen("second") + 1); 7231 CU_ASSERT(rc == 0); 7232 CU_ASSERT(g_bserrno == -1); 7233 7234 /* Keep g_bserrno at -1, only the 7235 * second sync completion should set it at 0. */ 7236 } 7237 7238 static void 7239 second_sync_complete(void *cb_arg, int bserrno) 7240 { 7241 struct spdk_blob *blob = cb_arg; 7242 const void *value; 7243 size_t value_len; 7244 int rc; 7245 7246 CU_ASSERT(bserrno == 0); 7247 7248 /* Verify that the first sync completion had a chance to execute */ 7249 rc = spdk_blob_get_xattr_value(blob, "sync", &value, &value_len); 7250 CU_ASSERT(rc == 0); 7251 SPDK_CU_ASSERT_FATAL(value != NULL); 7252 CU_ASSERT(value_len == strlen("second") + 1); 7253 CU_ASSERT_NSTRING_EQUAL_FATAL(value, "second", value_len); 7254 7255 CU_ASSERT(g_bserrno == -1); 7256 g_bserrno = bserrno; 7257 } 7258 7259 static void 7260 blob_simultaneous_operations(void) 7261 { 7262 struct spdk_blob_store *bs = g_bs; 7263 struct spdk_blob_opts opts; 7264 struct spdk_blob *blob, *snapshot; 7265 spdk_blob_id blobid, snapshotid; 7266 struct spdk_io_channel *channel; 7267 int rc; 7268 7269 channel = spdk_bs_alloc_io_channel(bs); 7270 SPDK_CU_ASSERT_FATAL(channel != NULL); 7271 7272 ut_spdk_blob_opts_init(&opts); 7273 opts.num_clusters = 10; 7274 7275 blob = ut_blob_create_and_open(bs, &opts); 7276 blobid = spdk_blob_get_id(blob); 7277 7278 /* Create snapshot and try to remove blob in the same time: 7279 * - snapshot should be created successfully 7280 * - delete operation should fail w -EBUSY */ 7281 CU_ASSERT(blob->locked_operation_in_progress == false); 7282 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 7283 CU_ASSERT(blob->locked_operation_in_progress == true); 7284 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7285 CU_ASSERT(blob->locked_operation_in_progress == true); 7286 /* Deletion failure */ 7287 CU_ASSERT(g_bserrno == -EBUSY); 7288 poll_threads(); 7289 CU_ASSERT(blob->locked_operation_in_progress == false); 7290 /* Snapshot creation success */ 7291 CU_ASSERT(g_bserrno == 0); 7292 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7293 7294 snapshotid = g_blobid; 7295 7296 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 7297 poll_threads(); 7298 CU_ASSERT(g_bserrno == 0); 7299 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7300 snapshot = g_blob; 7301 7302 /* Inflate blob and try to remove blob in the same time: 7303 * - blob should be inflated successfully 7304 * - delete operation should fail w -EBUSY */ 7305 CU_ASSERT(blob->locked_operation_in_progress == false); 7306 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 7307 CU_ASSERT(blob->locked_operation_in_progress == true); 7308 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7309 CU_ASSERT(blob->locked_operation_in_progress == true); 7310 /* Deletion failure */ 7311 CU_ASSERT(g_bserrno == -EBUSY); 7312 poll_threads(); 7313 CU_ASSERT(blob->locked_operation_in_progress == false); 7314 /* Inflation success */ 7315 CU_ASSERT(g_bserrno == 0); 7316 7317 /* Clone snapshot and try to remove snapshot in the same time: 7318 * - snapshot should be cloned successfully 7319 * - delete operation should fail w -EBUSY */ 7320 CU_ASSERT(blob->locked_operation_in_progress == false); 7321 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 7322 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 7323 /* Deletion failure */ 7324 CU_ASSERT(g_bserrno == -EBUSY); 7325 poll_threads(); 7326 CU_ASSERT(blob->locked_operation_in_progress == false); 7327 /* Clone created */ 7328 CU_ASSERT(g_bserrno == 0); 7329 7330 /* Resize blob and try to remove blob in the same time: 7331 * - blob should be resized successfully 7332 * - delete operation should fail w -EBUSY */ 7333 CU_ASSERT(blob->locked_operation_in_progress == false); 7334 spdk_blob_resize(blob, 50, blob_op_complete, NULL); 7335 CU_ASSERT(blob->locked_operation_in_progress == true); 7336 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 7337 CU_ASSERT(blob->locked_operation_in_progress == true); 7338 /* Deletion failure */ 7339 CU_ASSERT(g_bserrno == -EBUSY); 7340 poll_threads(); 7341 CU_ASSERT(blob->locked_operation_in_progress == false); 7342 /* Blob resized successfully */ 7343 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7344 poll_threads(); 7345 CU_ASSERT(g_bserrno == 0); 7346 7347 /* Issue two consecutive blob syncs, neither should fail. 7348 * Force sync to actually occur by marking blob dirty each time. 7349 * Execution of sync should not be enough to complete the operation, 7350 * since disk I/O is required to complete it. */ 7351 g_bserrno = -1; 7352 7353 rc = spdk_blob_set_xattr(blob, "sync", "first", strlen("first") + 1); 7354 CU_ASSERT(rc == 0); 7355 spdk_blob_sync_md(blob, first_sync_complete, blob); 7356 CU_ASSERT(g_bserrno == -1); 7357 7358 spdk_blob_sync_md(blob, second_sync_complete, blob); 7359 CU_ASSERT(g_bserrno == -1); 7360 7361 poll_threads(); 7362 CU_ASSERT(g_bserrno == 0); 7363 7364 spdk_bs_free_io_channel(channel); 7365 poll_threads(); 7366 7367 ut_blob_close_and_delete(bs, snapshot); 7368 ut_blob_close_and_delete(bs, blob); 7369 } 7370 7371 static void 7372 blob_persist_test(void) 7373 { 7374 struct spdk_blob_store *bs = g_bs; 7375 struct spdk_blob_opts opts; 7376 struct spdk_blob *blob; 7377 spdk_blob_id blobid; 7378 struct spdk_io_channel *channel; 7379 char *xattr; 7380 size_t xattr_length; 7381 int rc; 7382 uint32_t page_count_clear, page_count_xattr; 7383 uint64_t poller_iterations; 7384 bool run_poller; 7385 7386 channel = spdk_bs_alloc_io_channel(bs); 7387 SPDK_CU_ASSERT_FATAL(channel != NULL); 7388 7389 ut_spdk_blob_opts_init(&opts); 7390 opts.num_clusters = 10; 7391 7392 blob = ut_blob_create_and_open(bs, &opts); 7393 blobid = spdk_blob_get_id(blob); 7394 7395 /* Save the amount of md pages used after creation of a blob. 7396 * This should be consistent after removing xattr. */ 7397 page_count_clear = spdk_bit_array_count_set(bs->used_md_pages); 7398 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_clear); 7399 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_clear); 7400 7401 /* Add xattr with maximum length of descriptor to exceed single metadata page. */ 7402 xattr_length = SPDK_BS_MAX_DESC_SIZE - sizeof(struct spdk_blob_md_descriptor_xattr) - 7403 strlen("large_xattr"); 7404 xattr = calloc(xattr_length, sizeof(char)); 7405 SPDK_CU_ASSERT_FATAL(xattr != NULL); 7406 7407 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); 7408 SPDK_CU_ASSERT_FATAL(rc == 0); 7409 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7410 poll_threads(); 7411 SPDK_CU_ASSERT_FATAL(g_bserrno == 0); 7412 7413 /* Save the amount of md pages used after adding the large xattr */ 7414 page_count_xattr = spdk_bit_array_count_set(bs->used_md_pages); 7415 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_xattr); 7416 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_xattr); 7417 7418 /* Add xattr to a blob and sync it. While sync is occurring, remove the xattr and sync again. 7419 * Interrupt the first sync after increasing number of poller iterations, until it succeeds. 7420 * Expectation is that after second sync completes no xattr is saved in metadata. */ 7421 poller_iterations = 1; 7422 run_poller = true; 7423 while (run_poller) { 7424 rc = spdk_blob_set_xattr(blob, "large_xattr", xattr, xattr_length); 7425 SPDK_CU_ASSERT_FATAL(rc == 0); 7426 g_bserrno = -1; 7427 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7428 poll_thread_times(0, poller_iterations); 7429 if (g_bserrno == 0) { 7430 /* Poller iteration count was high enough for first sync to complete. 7431 * Verify that blob takes up enough of md_pages to store the xattr. */ 7432 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_xattr); 7433 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_xattr); 7434 SPDK_CU_ASSERT_FATAL(spdk_bit_array_count_set(bs->used_md_pages) == page_count_xattr); 7435 run_poller = false; 7436 } 7437 rc = spdk_blob_remove_xattr(blob, "large_xattr"); 7438 SPDK_CU_ASSERT_FATAL(rc == 0); 7439 spdk_blob_sync_md(blob, blob_op_complete, NULL); 7440 poll_threads(); 7441 SPDK_CU_ASSERT_FATAL(g_bserrno == 0); 7442 SPDK_CU_ASSERT_FATAL(blob->active.num_pages + blob->active.num_extent_pages == page_count_clear); 7443 SPDK_CU_ASSERT_FATAL(blob->clean.num_pages + blob->clean.num_extent_pages == page_count_clear); 7444 SPDK_CU_ASSERT_FATAL(spdk_bit_array_count_set(bs->used_md_pages) == page_count_clear); 7445 7446 /* Reload bs and re-open blob to verify that xattr was not persisted. */ 7447 spdk_blob_close(blob, blob_op_complete, NULL); 7448 poll_threads(); 7449 CU_ASSERT(g_bserrno == 0); 7450 7451 ut_bs_reload(&bs, NULL); 7452 7453 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7454 poll_threads(); 7455 CU_ASSERT(g_bserrno == 0); 7456 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7457 blob = g_blob; 7458 7459 rc = spdk_blob_get_xattr_value(blob, "large_xattr", (const void **)&xattr, &xattr_length); 7460 SPDK_CU_ASSERT_FATAL(rc == -ENOENT); 7461 7462 poller_iterations++; 7463 /* Stop at high iteration count to prevent infinite loop. 7464 * This value should be enough for first md sync to complete in any case. */ 7465 SPDK_CU_ASSERT_FATAL(poller_iterations < 50); 7466 } 7467 7468 free(xattr); 7469 7470 ut_blob_close_and_delete(bs, blob); 7471 7472 spdk_bs_free_io_channel(channel); 7473 poll_threads(); 7474 } 7475 7476 static void 7477 blob_decouple_snapshot(void) 7478 { 7479 struct spdk_blob_store *bs = g_bs; 7480 struct spdk_blob_opts opts; 7481 struct spdk_blob *blob, *snapshot1, *snapshot2; 7482 struct spdk_io_channel *channel; 7483 spdk_blob_id blobid, snapshotid; 7484 uint64_t cluster; 7485 7486 for (int delete_snapshot_first = 0; delete_snapshot_first <= 1; delete_snapshot_first++) { 7487 channel = spdk_bs_alloc_io_channel(bs); 7488 SPDK_CU_ASSERT_FATAL(channel != NULL); 7489 7490 ut_spdk_blob_opts_init(&opts); 7491 opts.num_clusters = 10; 7492 opts.thin_provision = false; 7493 7494 blob = ut_blob_create_and_open(bs, &opts); 7495 blobid = spdk_blob_get_id(blob); 7496 7497 /* Create first snapshot */ 7498 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 0); 7499 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 7500 poll_threads(); 7501 CU_ASSERT(g_bserrno == 0); 7502 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7503 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1); 7504 snapshotid = g_blobid; 7505 7506 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 7507 poll_threads(); 7508 CU_ASSERT(g_bserrno == 0); 7509 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7510 snapshot1 = g_blob; 7511 7512 /* Create the second one */ 7513 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 1); 7514 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 7515 poll_threads(); 7516 CU_ASSERT(g_bserrno == 0); 7517 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7518 CU_ASSERT_EQUAL(_get_snapshots_count(bs), 2); 7519 snapshotid = g_blobid; 7520 7521 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 7522 poll_threads(); 7523 CU_ASSERT(g_bserrno == 0); 7524 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 7525 snapshot2 = g_blob; 7526 CU_ASSERT_EQUAL(spdk_blob_get_parent_snapshot(bs, snapshot2->id), snapshot1->id); 7527 7528 /* Now decouple the second snapshot forcing it to copy the written clusters */ 7529 spdk_bs_blob_decouple_parent(bs, channel, snapshot2->id, blob_op_complete, NULL); 7530 poll_threads(); 7531 CU_ASSERT(g_bserrno == 0); 7532 7533 /* Verify that the snapshot has been decoupled and that the clusters have been copied */ 7534 CU_ASSERT_EQUAL(spdk_blob_get_parent_snapshot(bs, snapshot2->id), SPDK_BLOBID_INVALID); 7535 for (cluster = 0; cluster < snapshot2->active.num_clusters; ++cluster) { 7536 CU_ASSERT_NOT_EQUAL(snapshot2->active.clusters[cluster], 0); 7537 CU_ASSERT_NOT_EQUAL(snapshot2->active.clusters[cluster], 7538 snapshot1->active.clusters[cluster]); 7539 } 7540 7541 spdk_bs_free_io_channel(channel); 7542 7543 if (delete_snapshot_first) { 7544 ut_blob_close_and_delete(bs, snapshot2); 7545 ut_blob_close_and_delete(bs, snapshot1); 7546 ut_blob_close_and_delete(bs, blob); 7547 } else { 7548 ut_blob_close_and_delete(bs, blob); 7549 ut_blob_close_and_delete(bs, snapshot2); 7550 ut_blob_close_and_delete(bs, snapshot1); 7551 } 7552 poll_threads(); 7553 } 7554 } 7555 7556 static void 7557 blob_seek_io_unit(void) 7558 { 7559 struct spdk_blob_store *bs = g_bs; 7560 struct spdk_blob *blob; 7561 struct spdk_io_channel *channel; 7562 struct spdk_blob_opts opts; 7563 uint64_t free_clusters; 7564 uint8_t payload[10 * 4096]; 7565 uint64_t offset; 7566 uint64_t io_unit, io_units_per_cluster; 7567 7568 free_clusters = spdk_bs_free_cluster_count(bs); 7569 7570 channel = spdk_bs_alloc_io_channel(bs); 7571 CU_ASSERT(channel != NULL); 7572 7573 /* Set blob as thin provisioned */ 7574 ut_spdk_blob_opts_init(&opts); 7575 opts.thin_provision = true; 7576 7577 /* Create a blob */ 7578 blob = ut_blob_create_and_open(bs, &opts); 7579 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 7580 7581 io_units_per_cluster = bs_io_units_per_cluster(blob); 7582 7583 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 7584 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 7585 poll_threads(); 7586 CU_ASSERT(g_bserrno == 0); 7587 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 7588 CU_ASSERT(blob->active.num_clusters == 5); 7589 7590 /* Write at the beginning of first cluster */ 7591 offset = 0; 7592 spdk_blob_io_write(blob, channel, payload, offset, 1, blob_op_complete, NULL); 7593 poll_threads(); 7594 CU_ASSERT(g_bserrno == 0); 7595 7596 io_unit = spdk_blob_get_next_allocated_io_unit(blob, 0); 7597 CU_ASSERT(io_unit == offset); 7598 7599 io_unit = spdk_blob_get_next_unallocated_io_unit(blob, 0); 7600 CU_ASSERT(io_unit == io_units_per_cluster); 7601 7602 /* Write in the middle of third cluster */ 7603 offset = 2 * io_units_per_cluster + io_units_per_cluster / 2; 7604 spdk_blob_io_write(blob, channel, payload, offset, 1, blob_op_complete, NULL); 7605 poll_threads(); 7606 CU_ASSERT(g_bserrno == 0); 7607 7608 io_unit = spdk_blob_get_next_allocated_io_unit(blob, io_units_per_cluster); 7609 CU_ASSERT(io_unit == 2 * io_units_per_cluster); 7610 7611 io_unit = spdk_blob_get_next_unallocated_io_unit(blob, 2 * io_units_per_cluster); 7612 CU_ASSERT(io_unit == 3 * io_units_per_cluster); 7613 7614 /* Write at the end of last cluster */ 7615 offset = 5 * io_units_per_cluster - 1; 7616 spdk_blob_io_write(blob, channel, payload, offset, 1, blob_op_complete, NULL); 7617 poll_threads(); 7618 CU_ASSERT(g_bserrno == 0); 7619 7620 io_unit = spdk_blob_get_next_allocated_io_unit(blob, 3 * io_units_per_cluster); 7621 CU_ASSERT(io_unit == 4 * io_units_per_cluster); 7622 7623 io_unit = spdk_blob_get_next_unallocated_io_unit(blob, 4 * io_units_per_cluster); 7624 CU_ASSERT(io_unit == UINT64_MAX); 7625 7626 spdk_bs_free_io_channel(channel); 7627 poll_threads(); 7628 7629 ut_blob_close_and_delete(bs, blob); 7630 } 7631 7632 static void 7633 blob_esnap_create(void) 7634 { 7635 struct spdk_blob_store *bs = g_bs; 7636 struct spdk_bs_opts bs_opts; 7637 struct ut_esnap_opts esnap_opts; 7638 struct spdk_blob_opts opts; 7639 struct spdk_blob_open_opts open_opts; 7640 struct spdk_blob *blob; 7641 uint32_t cluster_sz, block_sz; 7642 const uint32_t esnap_num_clusters = 4; 7643 uint64_t esnap_num_blocks; 7644 uint32_t sz; 7645 spdk_blob_id blobid; 7646 uint32_t bs_ctx_count, blob_ctx_count; 7647 7648 cluster_sz = spdk_bs_get_cluster_size(bs); 7649 block_sz = spdk_bs_get_io_unit_size(bs); 7650 esnap_num_blocks = cluster_sz * esnap_num_clusters / block_sz; 7651 7652 /* Create a normal blob and verify it is not an esnap clone. */ 7653 ut_spdk_blob_opts_init(&opts); 7654 blob = ut_blob_create_and_open(bs, &opts); 7655 CU_ASSERT(!spdk_blob_is_esnap_clone(blob)); 7656 ut_blob_close_and_delete(bs, blob); 7657 7658 /* Create an esnap clone blob then verify it is an esnap clone and has the right size */ 7659 ut_spdk_blob_opts_init(&opts); 7660 ut_esnap_opts_init(block_sz, esnap_num_blocks, __func__, NULL, &esnap_opts); 7661 opts.esnap_id = &esnap_opts; 7662 opts.esnap_id_len = sizeof(esnap_opts); 7663 opts.num_clusters = esnap_num_clusters; 7664 blob = ut_blob_create_and_open(bs, &opts); 7665 SPDK_CU_ASSERT_FATAL(blob != NULL); 7666 SPDK_CU_ASSERT_FATAL(spdk_blob_is_esnap_clone(blob)); 7667 SPDK_CU_ASSERT_FATAL(blob_is_esnap_clone(blob)); 7668 SPDK_CU_ASSERT_FATAL(!spdk_blob_is_clone(blob)); 7669 sz = spdk_blob_get_num_clusters(blob); 7670 CU_ASSERT(sz == esnap_num_clusters); 7671 ut_blob_close_and_delete(bs, blob); 7672 7673 /* Create an esnap clone without the size and verify it can be grown */ 7674 ut_spdk_blob_opts_init(&opts); 7675 ut_esnap_opts_init(block_sz, esnap_num_blocks, __func__, NULL, &esnap_opts); 7676 opts.esnap_id = &esnap_opts; 7677 opts.esnap_id_len = sizeof(esnap_opts); 7678 blob = ut_blob_create_and_open(bs, &opts); 7679 SPDK_CU_ASSERT_FATAL(spdk_blob_is_esnap_clone(blob)); 7680 sz = spdk_blob_get_num_clusters(blob); 7681 CU_ASSERT(sz == 0); 7682 spdk_blob_resize(blob, 1, blob_op_complete, NULL); 7683 poll_threads(); 7684 CU_ASSERT(g_bserrno == 0); 7685 sz = spdk_blob_get_num_clusters(blob); 7686 CU_ASSERT(sz == 1); 7687 spdk_blob_resize(blob, esnap_num_clusters, blob_op_complete, NULL); 7688 poll_threads(); 7689 CU_ASSERT(g_bserrno == 0); 7690 sz = spdk_blob_get_num_clusters(blob); 7691 CU_ASSERT(sz == esnap_num_clusters); 7692 spdk_blob_resize(blob, esnap_num_clusters + 1, blob_op_complete, NULL); 7693 poll_threads(); 7694 CU_ASSERT(g_bserrno == 0); 7695 sz = spdk_blob_get_num_clusters(blob); 7696 CU_ASSERT(sz == esnap_num_clusters + 1); 7697 7698 /* Reload the blobstore and be sure that the blob can be opened. */ 7699 blobid = spdk_blob_get_id(blob); 7700 spdk_blob_close(blob, blob_op_complete, NULL); 7701 poll_threads(); 7702 CU_ASSERT(g_bserrno == 0); 7703 g_blob = NULL; 7704 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 7705 bs_opts.esnap_bs_dev_create = ut_esnap_create; 7706 ut_bs_reload(&bs, &bs_opts); 7707 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7708 poll_threads(); 7709 CU_ASSERT(g_bserrno == 0); 7710 CU_ASSERT(g_blob != NULL); 7711 blob = g_blob; 7712 SPDK_CU_ASSERT_FATAL(spdk_blob_is_esnap_clone(blob)); 7713 sz = spdk_blob_get_num_clusters(blob); 7714 CU_ASSERT(sz == esnap_num_clusters + 1); 7715 7716 /* Reload the blobstore without esnap_bs_dev_create: should fail to open blob. */ 7717 spdk_blob_close(blob, blob_op_complete, NULL); 7718 poll_threads(); 7719 CU_ASSERT(g_bserrno == 0); 7720 g_blob = NULL; 7721 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 7722 ut_bs_reload(&bs, &bs_opts); 7723 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7724 poll_threads(); 7725 CU_ASSERT(g_bserrno != 0); 7726 CU_ASSERT(g_blob == NULL); 7727 7728 /* Reload the blobstore with ctx set and verify it is passed to the esnap create callback */ 7729 bs_ctx_count = 0; 7730 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 7731 bs_opts.esnap_bs_dev_create = ut_esnap_create_with_count; 7732 bs_opts.esnap_ctx = &bs_ctx_count; 7733 ut_bs_reload(&bs, &bs_opts); 7734 /* Loading the blobstore triggers the esnap to be loaded */ 7735 CU_ASSERT(bs_ctx_count == 1); 7736 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 7737 poll_threads(); 7738 CU_ASSERT(g_bserrno == 0); 7739 CU_ASSERT(g_blob != NULL); 7740 /* Opening the blob also triggers the esnap to be loaded */ 7741 CU_ASSERT(bs_ctx_count == 2); 7742 blob = g_blob; 7743 SPDK_CU_ASSERT_FATAL(spdk_blob_is_esnap_clone(blob)); 7744 sz = spdk_blob_get_num_clusters(blob); 7745 CU_ASSERT(sz == esnap_num_clusters + 1); 7746 spdk_blob_close(blob, blob_op_complete, NULL); 7747 poll_threads(); 7748 CU_ASSERT(g_bserrno == 0); 7749 g_blob = NULL; 7750 /* If open_opts.esnap_ctx is set it is passed to the esnap create callback */ 7751 blob_ctx_count = 0; 7752 spdk_blob_open_opts_init(&open_opts, sizeof(open_opts)); 7753 open_opts.esnap_ctx = &blob_ctx_count; 7754 spdk_bs_open_blob_ext(bs, blobid, &open_opts, blob_op_with_handle_complete, NULL); 7755 poll_threads(); 7756 blob = g_blob; 7757 CU_ASSERT(bs_ctx_count == 3); 7758 CU_ASSERT(blob_ctx_count == 1); 7759 spdk_blob_close(blob, blob_op_complete, NULL); 7760 poll_threads(); 7761 CU_ASSERT(g_bserrno == 0); 7762 g_blob = NULL; 7763 } 7764 7765 static void 7766 blob_esnap_clone_reload(void) 7767 { 7768 struct spdk_blob_store *bs = g_bs; 7769 struct spdk_bs_opts bs_opts; 7770 struct ut_esnap_opts esnap_opts; 7771 struct spdk_blob_opts opts; 7772 struct spdk_blob *eclone1, *snap1, *clone1; 7773 uint32_t cluster_sz = spdk_bs_get_cluster_size(bs); 7774 uint32_t block_sz = spdk_bs_get_io_unit_size(bs); 7775 const uint32_t esnap_num_clusters = 4; 7776 uint64_t esnap_num_blocks = cluster_sz * esnap_num_clusters / block_sz; 7777 spdk_blob_id eclone1_id, snap1_id, clone1_id; 7778 struct spdk_io_channel *bs_ch; 7779 char buf[block_sz]; 7780 int bserr1, bserr2, bserr3, bserr4; 7781 struct spdk_bs_dev *dev; 7782 7783 /* Create and open an esnap clone blob */ 7784 ut_spdk_blob_opts_init(&opts); 7785 ut_esnap_opts_init(block_sz, esnap_num_blocks, __func__, NULL, &esnap_opts); 7786 opts.esnap_id = &esnap_opts; 7787 opts.esnap_id_len = sizeof(esnap_opts); 7788 opts.num_clusters = esnap_num_clusters; 7789 eclone1 = ut_blob_create_and_open(bs, &opts); 7790 CU_ASSERT(eclone1 != NULL); 7791 CU_ASSERT(spdk_blob_is_esnap_clone(eclone1)); 7792 eclone1_id = eclone1->id; 7793 7794 /* Create and open a snapshot of eclone1 */ 7795 spdk_bs_create_snapshot(bs, eclone1_id, NULL, blob_op_with_id_complete, NULL); 7796 poll_threads(); 7797 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7798 CU_ASSERT(g_bserrno == 0); 7799 snap1_id = g_blobid; 7800 spdk_bs_open_blob(bs, snap1_id, blob_op_with_handle_complete, NULL); 7801 poll_threads(); 7802 CU_ASSERT(g_bserrno == 0); 7803 CU_ASSERT(g_blob != NULL); 7804 snap1 = g_blob; 7805 7806 /* Create and open regular clone of snap1 */ 7807 spdk_bs_create_clone(bs, snap1_id, NULL, blob_op_with_id_complete, NULL); 7808 poll_threads(); 7809 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 7810 SPDK_CU_ASSERT_FATAL(g_bserrno == 0); 7811 clone1_id = g_blobid; 7812 spdk_bs_open_blob(bs, clone1_id, blob_op_with_handle_complete, NULL); 7813 poll_threads(); 7814 CU_ASSERT(g_bserrno == 0); 7815 CU_ASSERT(g_blob != NULL); 7816 clone1 = g_blob; 7817 7818 /* Close the blobs in preparation for reloading the blobstore */ 7819 spdk_blob_close(clone1, blob_op_complete, NULL); 7820 poll_threads(); 7821 CU_ASSERT(g_bserrno == 0); 7822 spdk_blob_close(snap1, blob_op_complete, NULL); 7823 poll_threads(); 7824 CU_ASSERT(g_bserrno == 0); 7825 spdk_blob_close(eclone1, blob_op_complete, NULL); 7826 poll_threads(); 7827 CU_ASSERT(g_bserrno == 0); 7828 g_blob = NULL; 7829 7830 /* Reload the blobstore */ 7831 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 7832 bs_opts.esnap_bs_dev_create = ut_esnap_create; 7833 ut_bs_reload(&bs, &bs_opts); 7834 7835 /* Be sure each of the blobs can be opened */ 7836 spdk_bs_open_blob(bs, eclone1_id, blob_op_with_handle_complete, NULL); 7837 poll_threads(); 7838 CU_ASSERT(g_bserrno == 0); 7839 CU_ASSERT(g_blob != NULL); 7840 eclone1 = g_blob; 7841 spdk_bs_open_blob(bs, snap1_id, blob_op_with_handle_complete, NULL); 7842 poll_threads(); 7843 CU_ASSERT(g_bserrno == 0); 7844 CU_ASSERT(g_blob != NULL); 7845 snap1 = g_blob; 7846 spdk_bs_open_blob(bs, clone1_id, blob_op_with_handle_complete, NULL); 7847 poll_threads(); 7848 CU_ASSERT(g_bserrno == 0); 7849 CU_ASSERT(g_blob != NULL); 7850 clone1 = g_blob; 7851 7852 /* Perform some reads on each of them to cause channels to be allocated */ 7853 bs_ch = spdk_bs_alloc_io_channel(bs); 7854 CU_ASSERT(bs_ch != NULL); 7855 spdk_blob_io_read(eclone1, bs_ch, buf, 0, 1, bs_op_complete, NULL); 7856 poll_threads(); 7857 CU_ASSERT(g_bserrno == 0); 7858 spdk_blob_io_read(snap1, bs_ch, buf, 0, 1, bs_op_complete, NULL); 7859 poll_threads(); 7860 CU_ASSERT(g_bserrno == 0); 7861 spdk_blob_io_read(clone1, bs_ch, buf, 0, 1, bs_op_complete, NULL); 7862 poll_threads(); 7863 CU_ASSERT(g_bserrno == 0); 7864 7865 /* 7866 * Unload the blobstore in a way similar to how lvstore unloads it. This should exercise 7867 * the deferred unload path in spdk_bs_unload(). 7868 */ 7869 bserr1 = 0xbad; 7870 bserr2 = 0xbad; 7871 bserr3 = 0xbad; 7872 bserr4 = 0xbad; 7873 spdk_blob_close(eclone1, blob_op_complete, &bserr1); 7874 spdk_blob_close(snap1, blob_op_complete, &bserr2); 7875 spdk_blob_close(clone1, blob_op_complete, &bserr3); 7876 spdk_bs_unload(bs, blob_op_complete, &bserr4); 7877 spdk_bs_free_io_channel(bs_ch); 7878 poll_threads(); 7879 CU_ASSERT(bserr1 == 0); 7880 CU_ASSERT(bserr2 == 0); 7881 CU_ASSERT(bserr3 == 0); 7882 CU_ASSERT(bserr4 == 0); 7883 g_blob = NULL; 7884 7885 /* Reload the blobstore */ 7886 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 7887 bs_opts.esnap_bs_dev_create = ut_esnap_create; 7888 dev = init_dev(); 7889 spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL); 7890 poll_threads(); 7891 CU_ASSERT(g_bserrno == 0); 7892 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7893 } 7894 7895 static bool 7896 blob_esnap_verify_contents(struct spdk_blob *blob, struct spdk_io_channel *ch, 7897 uint64_t offset, uint64_t size, uint32_t readsize, const char *how) 7898 { 7899 const uint32_t bs_blksz = blob->bs->io_unit_size; 7900 const uint32_t esnap_blksz = blob->back_bs_dev ? blob->back_bs_dev->blocklen : bs_blksz; 7901 const uint32_t start_blk = offset / bs_blksz; 7902 const uint32_t num_blocks = spdk_max(size, readsize) / bs_blksz; 7903 const uint32_t blocks_per_read = spdk_min(size, readsize) / bs_blksz; 7904 uint32_t blob_block; 7905 struct iovec iov; 7906 uint8_t buf[spdk_min(size, readsize)]; 7907 bool block_ok; 7908 7909 SPDK_CU_ASSERT_FATAL(offset % bs_blksz == 0); 7910 SPDK_CU_ASSERT_FATAL(size % bs_blksz == 0); 7911 SPDK_CU_ASSERT_FATAL(readsize % bs_blksz == 0); 7912 7913 memset(buf, 0, readsize); 7914 iov.iov_base = buf; 7915 iov.iov_len = readsize; 7916 for (blob_block = start_blk; blob_block < num_blocks; blob_block += blocks_per_read) { 7917 if (strcmp(how, "read") == 0) { 7918 spdk_blob_io_read(blob, ch, buf, blob_block, blocks_per_read, 7919 bs_op_complete, NULL); 7920 } else if (strcmp(how, "readv") == 0) { 7921 spdk_blob_io_readv(blob, ch, &iov, 1, blob_block, blocks_per_read, 7922 bs_op_complete, NULL); 7923 } else if (strcmp(how, "readv_ext") == 0) { 7924 /* 7925 * This is currently pointless. NULL ext_opts leads to dev->readv(), not 7926 * dev->readv_ext(). 7927 */ 7928 spdk_blob_io_readv_ext(blob, ch, &iov, 1, blob_block, blocks_per_read, 7929 bs_op_complete, NULL, NULL); 7930 } else { 7931 abort(); 7932 } 7933 poll_threads(); 7934 CU_ASSERT(g_bserrno == 0); 7935 if (g_bserrno != 0) { 7936 return false; 7937 } 7938 block_ok = ut_esnap_content_is_correct(buf, blocks_per_read * bs_blksz, blob->id, 7939 blob_block * bs_blksz, esnap_blksz); 7940 CU_ASSERT(block_ok); 7941 if (!block_ok) { 7942 return false; 7943 } 7944 } 7945 7946 return true; 7947 } 7948 7949 static void 7950 blob_esnap_io_size(uint32_t bs_blksz, uint32_t esnap_blksz) 7951 { 7952 struct spdk_bs_dev *dev; 7953 struct spdk_blob_store *bs; 7954 struct spdk_bs_opts bsopts; 7955 struct spdk_blob_opts opts; 7956 struct ut_esnap_opts esnap_opts; 7957 struct spdk_blob *blob; 7958 const uint32_t cluster_sz = 16 * 1024; 7959 const uint64_t esnap_num_clusters = 4; 7960 const uint32_t esnap_sz = cluster_sz * esnap_num_clusters; 7961 const uint64_t esnap_num_blocks = esnap_sz / esnap_blksz; 7962 const uint64_t blob_num_blocks = esnap_sz / bs_blksz; 7963 uint32_t block; 7964 struct spdk_io_channel *bs_ch; 7965 7966 spdk_bs_opts_init(&bsopts, sizeof(bsopts)); 7967 bsopts.cluster_sz = cluster_sz; 7968 bsopts.esnap_bs_dev_create = ut_esnap_create; 7969 7970 /* Create device with desired block size */ 7971 dev = init_dev(); 7972 dev->blocklen = bs_blksz; 7973 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 7974 7975 /* Initialize a new blob store */ 7976 spdk_bs_init(dev, &bsopts, bs_op_with_handle_complete, NULL); 7977 poll_threads(); 7978 CU_ASSERT(g_bserrno == 0); 7979 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 7980 SPDK_CU_ASSERT_FATAL(g_bs->io_unit_size == bs_blksz); 7981 bs = g_bs; 7982 7983 bs_ch = spdk_bs_alloc_io_channel(bs); 7984 SPDK_CU_ASSERT_FATAL(bs_ch != NULL); 7985 7986 /* Create and open the esnap clone */ 7987 ut_spdk_blob_opts_init(&opts); 7988 ut_esnap_opts_init(esnap_blksz, esnap_num_blocks, __func__, NULL, &esnap_opts); 7989 opts.esnap_id = &esnap_opts; 7990 opts.esnap_id_len = sizeof(esnap_opts); 7991 opts.num_clusters = esnap_num_clusters; 7992 blob = ut_blob_create_and_open(bs, &opts); 7993 SPDK_CU_ASSERT_FATAL(blob != NULL); 7994 7995 /* Verify that large reads return the content of the esnap device */ 7996 CU_ASSERT(blob_esnap_verify_contents(blob, bs_ch, 0, esnap_sz, esnap_sz, "read")); 7997 CU_ASSERT(blob_esnap_verify_contents(blob, bs_ch, 0, esnap_sz, esnap_sz, "readv")); 7998 CU_ASSERT(blob_esnap_verify_contents(blob, bs_ch, 0, esnap_sz, esnap_sz, "readv_ext")); 7999 /* Verify that small reads return the content of the esnap device */ 8000 CU_ASSERT(blob_esnap_verify_contents(blob, bs_ch, 0, esnap_sz, bs_blksz, "read")); 8001 CU_ASSERT(blob_esnap_verify_contents(blob, bs_ch, 0, esnap_sz, bs_blksz, "readv")); 8002 CU_ASSERT(blob_esnap_verify_contents(blob, bs_ch, 0, esnap_sz, bs_blksz, "readv_ext")); 8003 8004 /* Write one blob block at a time; verify that the surrounding blocks are OK */ 8005 for (block = 0; block < blob_num_blocks; block++) { 8006 char buf[bs_blksz]; 8007 union ut_word word; 8008 8009 word.f.blob_id = 0xfedcba90; 8010 word.f.lba = block; 8011 ut_memset8(buf, word.num, bs_blksz); 8012 8013 spdk_blob_io_write(blob, bs_ch, buf, block, 1, bs_op_complete, NULL); 8014 poll_threads(); 8015 CU_ASSERT(g_bserrno == 0); 8016 if (g_bserrno != 0) { 8017 break; 8018 } 8019 8020 /* Read and verify the block before the current block */ 8021 if (block != 0) { 8022 spdk_blob_io_read(blob, bs_ch, buf, block - 1, 1, bs_op_complete, NULL); 8023 poll_threads(); 8024 CU_ASSERT(g_bserrno == 0); 8025 if (g_bserrno != 0) { 8026 break; 8027 } 8028 CU_ASSERT(ut_esnap_content_is_correct(buf, bs_blksz, word.f.blob_id, 8029 (block - 1) * bs_blksz, bs_blksz)); 8030 } 8031 8032 /* Read and verify the current block */ 8033 spdk_blob_io_read(blob, bs_ch, buf, block, 1, bs_op_complete, NULL); 8034 poll_threads(); 8035 CU_ASSERT(g_bserrno == 0); 8036 if (g_bserrno != 0) { 8037 break; 8038 } 8039 CU_ASSERT(ut_esnap_content_is_correct(buf, bs_blksz, word.f.blob_id, 8040 block * bs_blksz, bs_blksz)); 8041 8042 /* Check the block that follows */ 8043 if (block + 1 < blob_num_blocks) { 8044 g_bserrno = 0xbad; 8045 spdk_blob_io_read(blob, bs_ch, buf, block + 1, 1, bs_op_complete, NULL); 8046 poll_threads(); 8047 CU_ASSERT(g_bserrno == 0); 8048 if (g_bserrno != 0) { 8049 break; 8050 } 8051 CU_ASSERT(ut_esnap_content_is_correct(buf, bs_blksz, blob->id, 8052 (block + 1) * bs_blksz, 8053 esnap_blksz)); 8054 } 8055 } 8056 8057 /* Clean up */ 8058 spdk_bs_free_io_channel(bs_ch); 8059 g_bserrno = 0xbad; 8060 spdk_blob_close(blob, blob_op_complete, NULL); 8061 poll_threads(); 8062 CU_ASSERT(g_bserrno == 0); 8063 spdk_bs_unload(g_bs, bs_op_complete, NULL); 8064 poll_threads(); 8065 CU_ASSERT(g_bserrno == 0); 8066 g_bs = NULL; 8067 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 8068 } 8069 8070 static void 8071 blob_esnap_io_4096_4096(void) 8072 { 8073 blob_esnap_io_size(4096, 4096); 8074 } 8075 8076 static void 8077 blob_esnap_io_512_512(void) 8078 { 8079 blob_esnap_io_size(512, 512); 8080 } 8081 8082 static void 8083 blob_esnap_io_4096_512(void) 8084 { 8085 blob_esnap_io_size(4096, 512); 8086 } 8087 8088 static void 8089 blob_esnap_io_512_4096(void) 8090 { 8091 struct spdk_bs_dev *dev; 8092 struct spdk_blob_store *bs; 8093 struct spdk_bs_opts bs_opts; 8094 struct spdk_blob_opts blob_opts; 8095 struct ut_esnap_opts esnap_opts; 8096 uint64_t cluster_sz = 16 * 1024; 8097 uint32_t bs_blksz = 512; 8098 uint32_t esnap_blksz = 4096; 8099 uint64_t esnap_num_blocks = 64; 8100 spdk_blob_id blobid; 8101 8102 /* Create device with desired block size */ 8103 dev = init_dev(); 8104 dev->blocklen = bs_blksz; 8105 dev->blockcnt = DEV_BUFFER_SIZE / dev->blocklen; 8106 8107 /* Initialize a new blob store */ 8108 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 8109 bs_opts.cluster_sz = cluster_sz; 8110 bs_opts.esnap_bs_dev_create = ut_esnap_create; 8111 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 8112 poll_threads(); 8113 CU_ASSERT(g_bserrno == 0); 8114 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 8115 SPDK_CU_ASSERT_FATAL(g_bs->io_unit_size == bs_blksz); 8116 bs = g_bs; 8117 8118 /* Try to create and open the esnap clone. Create should succeed, open should fail. */ 8119 ut_spdk_blob_opts_init(&blob_opts); 8120 ut_esnap_opts_init(esnap_blksz, esnap_num_blocks, __func__, NULL, &esnap_opts); 8121 blob_opts.esnap_id = &esnap_opts; 8122 blob_opts.esnap_id_len = sizeof(esnap_opts); 8123 blob_opts.num_clusters = esnap_num_blocks * esnap_blksz / bs_blksz; 8124 spdk_bs_create_blob_ext(bs, &blob_opts, blob_op_with_id_complete, NULL); 8125 poll_threads(); 8126 CU_ASSERT(g_bserrno == 0); 8127 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 8128 blobid = g_blobid; 8129 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 8130 poll_threads(); 8131 CU_ASSERT(g_bserrno == -EINVAL); 8132 CU_ASSERT(g_blob == NULL); 8133 8134 /* Clean up */ 8135 spdk_bs_unload(bs, bs_op_complete, NULL); 8136 poll_threads(); 8137 CU_ASSERT(g_bserrno == 0); 8138 g_bs = NULL; 8139 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 8140 } 8141 8142 static void 8143 blob_esnap_thread_add_remove(void) 8144 { 8145 struct spdk_blob_store *bs = g_bs; 8146 struct spdk_blob_opts opts; 8147 struct ut_esnap_opts ut_esnap_opts; 8148 struct spdk_blob *blob; 8149 struct ut_esnap_dev *ut_dev; 8150 spdk_blob_id blobid; 8151 uint64_t start_thread = g_ut_thread_id; 8152 bool destroyed = false; 8153 struct spdk_io_channel *ch0, *ch1; 8154 struct ut_esnap_channel *ut_ch0, *ut_ch1; 8155 const uint32_t blocklen = bs->io_unit_size; 8156 char buf[blocklen * 4]; 8157 8158 SPDK_CU_ASSERT_FATAL(g_ut_num_threads > 1); 8159 set_thread(0); 8160 8161 /* Create the esnap clone */ 8162 ut_esnap_opts_init(blocklen, 2048, "add_remove_1", &destroyed, &ut_esnap_opts); 8163 ut_spdk_blob_opts_init(&opts); 8164 opts.esnap_id = &ut_esnap_opts; 8165 opts.esnap_id_len = sizeof(ut_esnap_opts); 8166 opts.num_clusters = 10; 8167 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 8168 poll_threads(); 8169 CU_ASSERT(g_bserrno == 0); 8170 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 8171 blobid = g_blobid; 8172 8173 /* Open the blob. No channels should be allocated yet. */ 8174 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 8175 poll_threads(); 8176 CU_ASSERT(g_bserrno == 0); 8177 CU_ASSERT(g_blob != NULL); 8178 blob = g_blob; 8179 ut_dev = (struct ut_esnap_dev *)blob->back_bs_dev; 8180 CU_ASSERT(ut_dev != NULL); 8181 CU_ASSERT(ut_dev->num_channels == 0); 8182 8183 /* Create a channel on thread 0. It is lazily created on the first read. */ 8184 ch0 = spdk_bs_alloc_io_channel(bs); 8185 CU_ASSERT(ch0 != NULL); 8186 ut_ch0 = ut_esnap_get_io_channel(ch0, blobid); 8187 CU_ASSERT(ut_ch0 == NULL); 8188 CU_ASSERT(ut_dev->num_channels == 0); 8189 spdk_blob_io_read(blob, ch0, buf, 0, 1, bs_op_complete, NULL); 8190 poll_threads(); 8191 CU_ASSERT(g_bserrno == 0); 8192 CU_ASSERT(ut_dev->num_channels == 1); 8193 ut_ch0 = ut_esnap_get_io_channel(ch0, blobid); 8194 CU_ASSERT(ut_ch0 != NULL); 8195 CU_ASSERT(ut_ch0->blocks_read == 1); 8196 8197 /* Create a channel on thread 1 and verify its lazy creation too. */ 8198 set_thread(1); 8199 ch1 = spdk_bs_alloc_io_channel(bs); 8200 CU_ASSERT(ch1 != NULL); 8201 ut_ch1 = ut_esnap_get_io_channel(ch1, blobid); 8202 CU_ASSERT(ut_ch1 == NULL); 8203 CU_ASSERT(ut_dev->num_channels == 1); 8204 spdk_blob_io_read(blob, ch1, buf, 0, 4, bs_op_complete, NULL); 8205 poll_threads(); 8206 CU_ASSERT(g_bserrno == 0); 8207 CU_ASSERT(ut_dev->num_channels == 2); 8208 ut_ch1 = ut_esnap_get_io_channel(ch1, blobid); 8209 CU_ASSERT(ut_ch1 != NULL); 8210 CU_ASSERT(ut_ch1->blocks_read == 4); 8211 8212 /* Close the channel on thread 0 and verify the bs_dev channel is also gone. */ 8213 set_thread(0); 8214 spdk_bs_free_io_channel(ch0); 8215 poll_threads(); 8216 CU_ASSERT(ut_dev->num_channels == 1); 8217 8218 /* Close the blob. There is no outstanding IO so it should close right away. */ 8219 g_bserrno = 0xbad; 8220 spdk_blob_close(blob, blob_op_complete, NULL); 8221 poll_threads(); 8222 CU_ASSERT(g_bserrno == 0); 8223 CU_ASSERT(destroyed); 8224 8225 /* The esnap channel for the blob should be gone now too. */ 8226 ut_ch1 = ut_esnap_get_io_channel(ch1, blobid); 8227 CU_ASSERT(ut_ch1 == NULL); 8228 8229 /* Clean up */ 8230 set_thread(1); 8231 spdk_bs_free_io_channel(ch1); 8232 set_thread(start_thread); 8233 } 8234 8235 static void 8236 freeze_done(void *cb_arg, int bserrno) 8237 { 8238 uint32_t *freeze_cnt = cb_arg; 8239 8240 CU_ASSERT(bserrno == 0); 8241 (*freeze_cnt)++; 8242 } 8243 8244 static void 8245 unfreeze_done(void *cb_arg, int bserrno) 8246 { 8247 uint32_t *unfreeze_cnt = cb_arg; 8248 8249 CU_ASSERT(bserrno == 0); 8250 (*unfreeze_cnt)++; 8251 } 8252 8253 static void 8254 blob_nested_freezes(void) 8255 { 8256 struct spdk_blob_store *bs = g_bs; 8257 struct spdk_blob *blob; 8258 struct spdk_io_channel *channel[2]; 8259 struct spdk_blob_opts opts; 8260 uint32_t freeze_cnt, unfreeze_cnt; 8261 int i; 8262 8263 for (i = 0; i < 2; i++) { 8264 set_thread(i); 8265 channel[i] = spdk_bs_alloc_io_channel(bs); 8266 SPDK_CU_ASSERT_FATAL(channel[i] != NULL); 8267 } 8268 8269 set_thread(0); 8270 8271 ut_spdk_blob_opts_init(&opts); 8272 blob = ut_blob_create_and_open(bs, &opts); 8273 8274 /* First just test a single freeze/unfreeze. */ 8275 freeze_cnt = 0; 8276 unfreeze_cnt = 0; 8277 CU_ASSERT(blob->frozen_refcnt == 0); 8278 blob_freeze_io(blob, freeze_done, &freeze_cnt); 8279 CU_ASSERT(blob->frozen_refcnt == 1); 8280 CU_ASSERT(freeze_cnt == 0); 8281 poll_threads(); 8282 CU_ASSERT(freeze_cnt == 1); 8283 blob_unfreeze_io(blob, unfreeze_done, &unfreeze_cnt); 8284 CU_ASSERT(blob->frozen_refcnt == 0); 8285 CU_ASSERT(unfreeze_cnt == 0); 8286 poll_threads(); 8287 CU_ASSERT(unfreeze_cnt == 1); 8288 8289 /* Now nest multiple freeze/unfreeze operations. We should 8290 * expect a callback for each operation, but only after 8291 * the threads have been polled to ensure a for_each_channel() 8292 * was executed. 8293 */ 8294 freeze_cnt = 0; 8295 unfreeze_cnt = 0; 8296 CU_ASSERT(blob->frozen_refcnt == 0); 8297 blob_freeze_io(blob, freeze_done, &freeze_cnt); 8298 CU_ASSERT(blob->frozen_refcnt == 1); 8299 CU_ASSERT(freeze_cnt == 0); 8300 blob_freeze_io(blob, freeze_done, &freeze_cnt); 8301 CU_ASSERT(blob->frozen_refcnt == 2); 8302 CU_ASSERT(freeze_cnt == 0); 8303 poll_threads(); 8304 CU_ASSERT(freeze_cnt == 2); 8305 blob_unfreeze_io(blob, unfreeze_done, &unfreeze_cnt); 8306 CU_ASSERT(blob->frozen_refcnt == 1); 8307 CU_ASSERT(unfreeze_cnt == 0); 8308 blob_unfreeze_io(blob, unfreeze_done, &unfreeze_cnt); 8309 CU_ASSERT(blob->frozen_refcnt == 0); 8310 CU_ASSERT(unfreeze_cnt == 0); 8311 poll_threads(); 8312 CU_ASSERT(unfreeze_cnt == 2); 8313 8314 for (i = 0; i < 2; i++) { 8315 set_thread(i); 8316 spdk_bs_free_io_channel(channel[i]); 8317 } 8318 set_thread(0); 8319 ut_blob_close_and_delete(bs, blob); 8320 8321 poll_threads(); 8322 g_blob = NULL; 8323 g_blobid = 0; 8324 } 8325 8326 static void 8327 blob_ext_md_pages(void) 8328 { 8329 struct spdk_blob_store *bs; 8330 struct spdk_bs_dev *dev; 8331 struct spdk_blob *blob; 8332 struct spdk_blob_opts opts; 8333 struct spdk_bs_opts bs_opts; 8334 uint64_t free_clusters; 8335 8336 dev = init_dev(); 8337 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 8338 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 8339 /* Issue #2932 was a bug in how we use bs_allocate_cluster() during resize. 8340 * It requires num_md_pages that is much smaller than the number of clusters. 8341 * Make sure we can create a blob that uses all of the free clusters. 8342 */ 8343 bs_opts.cluster_sz = 65536; 8344 bs_opts.num_md_pages = 16; 8345 8346 /* Initialize a new blob store */ 8347 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 8348 poll_threads(); 8349 CU_ASSERT(g_bserrno == 0); 8350 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 8351 bs = g_bs; 8352 8353 free_clusters = spdk_bs_free_cluster_count(bs); 8354 8355 ut_spdk_blob_opts_init(&opts); 8356 opts.num_clusters = free_clusters; 8357 8358 blob = ut_blob_create_and_open(bs, &opts); 8359 spdk_blob_close(blob, blob_op_complete, NULL); 8360 CU_ASSERT(g_bserrno == 0); 8361 8362 spdk_bs_unload(bs, bs_op_complete, NULL); 8363 poll_threads(); 8364 CU_ASSERT(g_bserrno == 0); 8365 g_bs = NULL; 8366 } 8367 8368 static void 8369 blob_esnap_clone_snapshot(void) 8370 { 8371 /* 8372 * When a snapshot is created, the blob that is being snapped becomes 8373 * the leaf node (a clone of the snapshot) and the newly created 8374 * snapshot sits between the snapped blob and the external snapshot. 8375 * 8376 * Before creating snap1 8377 * 8378 * ,--------. ,----------. 8379 * | blob | | vbdev | 8380 * | blob1 |<----| nvme1n42 | 8381 * | (rw) | | (ro) | 8382 * `--------' `----------' 8383 * Figure 1 8384 * 8385 * After creating snap1 8386 * 8387 * ,--------. ,--------. ,----------. 8388 * | blob | | blob | | vbdev | 8389 * | blob1 |<----| snap1 |<----| nvme1n42 | 8390 * | (rw) | | (ro) | | (ro) | 8391 * `--------' `--------' `----------' 8392 * Figure 2 8393 * 8394 * Starting from Figure 2, if snap1 is removed, the chain reverts to 8395 * what it looks like in Figure 1. 8396 * 8397 * Starting from Figure 2, if blob1 is removed, the chain becomes: 8398 * 8399 * ,--------. ,----------. 8400 * | blob | | vbdev | 8401 * | snap1 |<----| nvme1n42 | 8402 * | (ro) | | (ro) | 8403 * `--------' `----------' 8404 * Figure 3 8405 * 8406 * In each case, the blob pointed to by the nvme vbdev is considered 8407 * the "esnap clone". The esnap clone must have: 8408 * 8409 * - XATTR_INTERNAL for BLOB_EXTERNAL_SNAPSHOT_ID (e.g. name or UUID) 8410 * - blob->invalid_flags must contain SPDK_BLOB_EXTERNAL_SNAPSHOT 8411 * - blob->parent_id must be SPDK_BLOBID_EXTERNAL_SNAPSHOT. 8412 * 8413 * No other blob that descends from the esnap clone may have any of 8414 * those set. 8415 */ 8416 struct spdk_blob_store *bs = g_bs; 8417 const uint32_t blocklen = bs->io_unit_size; 8418 struct spdk_blob_opts opts; 8419 struct ut_esnap_opts esnap_opts; 8420 struct spdk_blob *blob, *snap_blob; 8421 spdk_blob_id blobid, snap_blobid; 8422 bool destroyed = false; 8423 8424 /* Create the esnap clone */ 8425 ut_esnap_opts_init(blocklen, 2048, __func__, &destroyed, &esnap_opts); 8426 ut_spdk_blob_opts_init(&opts); 8427 opts.esnap_id = &esnap_opts; 8428 opts.esnap_id_len = sizeof(esnap_opts); 8429 opts.num_clusters = 10; 8430 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 8431 poll_threads(); 8432 CU_ASSERT(g_bserrno == 0); 8433 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 8434 blobid = g_blobid; 8435 8436 /* Open the blob. */ 8437 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 8438 poll_threads(); 8439 CU_ASSERT(g_bserrno == 0); 8440 CU_ASSERT(g_blob != NULL); 8441 blob = g_blob; 8442 UT_ASSERT_IS_ESNAP_CLONE(blob, &esnap_opts, sizeof(esnap_opts)); 8443 8444 /* 8445 * Create a snapshot of the blob. The snapshot becomes the esnap clone. 8446 */ 8447 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 8448 poll_threads(); 8449 CU_ASSERT(g_bserrno == 0); 8450 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 8451 snap_blobid = g_blobid; 8452 8453 spdk_bs_open_blob(bs, snap_blobid, blob_op_with_handle_complete, NULL); 8454 poll_threads(); 8455 CU_ASSERT(g_bserrno == 0); 8456 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 8457 snap_blob = g_blob; 8458 8459 UT_ASSERT_IS_NOT_ESNAP_CLONE(blob); 8460 UT_ASSERT_IS_ESNAP_CLONE(snap_blob, &esnap_opts, sizeof(esnap_opts)); 8461 8462 /* 8463 * Delete the snapshot. The original blob becomes the esnap clone. 8464 */ 8465 ut_blob_close_and_delete(bs, snap_blob); 8466 snap_blob = NULL; 8467 snap_blobid = SPDK_BLOBID_INVALID; 8468 UT_ASSERT_IS_ESNAP_CLONE(blob, &esnap_opts, sizeof(esnap_opts)); 8469 8470 /* 8471 * Create the snapshot again, then delete the original blob. The 8472 * snapshot should survive as the esnap clone. 8473 */ 8474 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 8475 poll_threads(); 8476 CU_ASSERT(g_bserrno == 0); 8477 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 8478 snap_blobid = g_blobid; 8479 8480 spdk_bs_open_blob(bs, snap_blobid, blob_op_with_handle_complete, NULL); 8481 poll_threads(); 8482 CU_ASSERT(g_bserrno == 0); 8483 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 8484 snap_blob = g_blob; 8485 8486 UT_ASSERT_IS_NOT_ESNAP_CLONE(blob); 8487 UT_ASSERT_IS_ESNAP_CLONE(snap_blob, &esnap_opts, sizeof(esnap_opts)); 8488 8489 ut_blob_close_and_delete(bs, blob); 8490 blob = NULL; 8491 blobid = SPDK_BLOBID_INVALID; 8492 UT_ASSERT_IS_ESNAP_CLONE(snap_blob, &esnap_opts, sizeof(esnap_opts)); 8493 8494 /* 8495 * Clone the snapshot. The snapshot continues to be the esnap clone. 8496 */ 8497 spdk_bs_create_clone(bs, snap_blobid, NULL, blob_op_with_id_complete, NULL); 8498 poll_threads(); 8499 CU_ASSERT(g_bserrno == 0); 8500 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 8501 blobid = g_blobid; 8502 8503 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 8504 poll_threads(); 8505 CU_ASSERT(g_bserrno == 0); 8506 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 8507 blob = g_blob; 8508 8509 UT_ASSERT_IS_NOT_ESNAP_CLONE(blob); 8510 UT_ASSERT_IS_ESNAP_CLONE(snap_blob, &esnap_opts, sizeof(esnap_opts)); 8511 8512 /* 8513 * Delete the snapshot. The clone becomes the esnap clone. 8514 */ 8515 ut_blob_close_and_delete(bs, snap_blob); 8516 snap_blob = NULL; 8517 snap_blobid = SPDK_BLOBID_INVALID; 8518 UT_ASSERT_IS_ESNAP_CLONE(blob, &esnap_opts, sizeof(esnap_opts)); 8519 8520 /* 8521 * Clean up 8522 */ 8523 ut_blob_close_and_delete(bs, blob); 8524 } 8525 8526 static uint64_t 8527 _blob_esnap_clone_hydrate(bool inflate) 8528 { 8529 struct spdk_blob_store *bs = g_bs; 8530 struct spdk_blob_opts opts; 8531 struct ut_esnap_opts esnap_opts; 8532 struct spdk_blob *blob; 8533 spdk_blob_id blobid; 8534 struct spdk_io_channel *channel; 8535 bool destroyed = false; 8536 const uint32_t blocklen = spdk_bs_get_io_unit_size(bs); 8537 const uint32_t cluster_sz = spdk_bs_get_cluster_size(bs); 8538 const uint64_t esnap_num_clusters = 4; 8539 const uint32_t esnap_sz = cluster_sz * esnap_num_clusters; 8540 const uint64_t esnap_num_blocks = esnap_sz / blocklen; 8541 uint64_t num_failures = CU_get_number_of_failures(); 8542 8543 channel = spdk_bs_alloc_io_channel(bs); 8544 SPDK_CU_ASSERT_FATAL(channel != NULL); 8545 8546 /* Create the esnap clone */ 8547 ut_spdk_blob_opts_init(&opts); 8548 ut_esnap_opts_init(blocklen, esnap_num_blocks, __func__, &destroyed, &esnap_opts); 8549 opts.esnap_id = &esnap_opts; 8550 opts.esnap_id_len = sizeof(esnap_opts); 8551 opts.num_clusters = esnap_num_clusters; 8552 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 8553 poll_threads(); 8554 CU_ASSERT(g_bserrno == 0); 8555 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 8556 blobid = g_blobid; 8557 8558 /* Open the esnap clone */ 8559 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 8560 poll_threads(); 8561 CU_ASSERT(g_bserrno == 0); 8562 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 8563 blob = g_blob; 8564 UT_ASSERT_IS_ESNAP_CLONE(blob, &esnap_opts, sizeof(esnap_opts)); 8565 8566 /* 8567 * Inflate or decouple the blob then verify that it is no longer an esnap clone and has 8568 * right content 8569 */ 8570 if (inflate) { 8571 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 8572 } else { 8573 spdk_bs_blob_decouple_parent(bs, channel, blobid, blob_op_complete, NULL); 8574 } 8575 poll_threads(); 8576 CU_ASSERT(g_bserrno == 0); 8577 UT_ASSERT_IS_NOT_ESNAP_CLONE(blob); 8578 CU_ASSERT(blob_esnap_verify_contents(blob, channel, 0, esnap_sz, esnap_sz, "read")); 8579 ut_blob_close_and_delete(bs, blob); 8580 8581 /* 8582 * Clean up 8583 */ 8584 spdk_bs_free_io_channel(channel); 8585 poll_threads(); 8586 8587 /* Return number of new failures */ 8588 return CU_get_number_of_failures() - num_failures; 8589 } 8590 8591 static void 8592 blob_esnap_clone_inflate(void) 8593 { 8594 _blob_esnap_clone_hydrate(true); 8595 } 8596 8597 static void 8598 blob_esnap_clone_decouple(void) 8599 { 8600 _blob_esnap_clone_hydrate(false); 8601 } 8602 8603 static void 8604 blob_esnap_hotplug(void) 8605 { 8606 struct spdk_blob_store *bs = g_bs; 8607 struct ut_esnap_opts esnap1_opts, esnap2_opts; 8608 struct spdk_blob_opts opts; 8609 struct spdk_blob *blob; 8610 struct spdk_bs_dev *bs_dev; 8611 struct ut_esnap_dev *esnap_dev; 8612 uint32_t cluster_sz = spdk_bs_get_cluster_size(bs); 8613 uint32_t block_sz = spdk_bs_get_io_unit_size(bs); 8614 const uint32_t esnap_num_clusters = 4; 8615 uint64_t esnap_num_blocks = cluster_sz * esnap_num_clusters / block_sz; 8616 bool destroyed1 = false, destroyed2 = false; 8617 uint64_t start_thread = g_ut_thread_id; 8618 struct spdk_io_channel *ch0, *ch1; 8619 char buf[block_sz]; 8620 8621 /* Create and open an esnap clone blob */ 8622 ut_spdk_blob_opts_init(&opts); 8623 ut_esnap_opts_init(block_sz, esnap_num_blocks, "esnap1", &destroyed1, &esnap1_opts); 8624 opts.esnap_id = &esnap1_opts; 8625 opts.esnap_id_len = sizeof(esnap1_opts); 8626 opts.num_clusters = esnap_num_clusters; 8627 blob = ut_blob_create_and_open(bs, &opts); 8628 CU_ASSERT(blob != NULL); 8629 CU_ASSERT(spdk_blob_is_esnap_clone(blob)); 8630 SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL); 8631 esnap_dev = (struct ut_esnap_dev *)blob->back_bs_dev; 8632 CU_ASSERT(strcmp(esnap_dev->ut_opts.name, "esnap1") == 0); 8633 8634 /* Replace the external snapshot */ 8635 ut_esnap_opts_init(block_sz, esnap_num_blocks, "esnap2", &destroyed2, &esnap2_opts); 8636 bs_dev = ut_esnap_dev_alloc(&esnap2_opts); 8637 CU_ASSERT(!destroyed1); 8638 CU_ASSERT(!destroyed2); 8639 g_bserrno = 0xbad; 8640 spdk_blob_set_esnap_bs_dev(blob, bs_dev, bs_op_complete, NULL); 8641 poll_threads(); 8642 CU_ASSERT(g_bserrno == 0); 8643 CU_ASSERT(destroyed1); 8644 CU_ASSERT(!destroyed2); 8645 SPDK_CU_ASSERT_FATAL(bs_dev == blob->back_bs_dev); 8646 SPDK_CU_ASSERT_FATAL(bs_dev == spdk_blob_get_esnap_bs_dev(blob)); 8647 esnap_dev = (struct ut_esnap_dev *)blob->back_bs_dev; 8648 CU_ASSERT(strcmp(esnap_dev->ut_opts.name, "esnap2") == 0); 8649 8650 /* Create a couple channels */ 8651 set_thread(0); 8652 ch0 = spdk_bs_alloc_io_channel(bs); 8653 CU_ASSERT(ch0 != NULL); 8654 spdk_blob_io_read(blob, ch0, buf, 0, 1, bs_op_complete, NULL); 8655 set_thread(1); 8656 ch1 = spdk_bs_alloc_io_channel(bs); 8657 CU_ASSERT(ch1 != NULL); 8658 spdk_blob_io_read(blob, ch1, buf, 0, 1, bs_op_complete, NULL); 8659 set_thread(start_thread); 8660 poll_threads(); 8661 CU_ASSERT(esnap_dev->num_channels == 2); 8662 8663 /* Replace the external snapshot */ 8664 ut_esnap_opts_init(block_sz, esnap_num_blocks, "esnap1a", &destroyed1, &esnap1_opts); 8665 bs_dev = ut_esnap_dev_alloc(&esnap1_opts); 8666 destroyed1 = destroyed2 = false; 8667 g_bserrno = 0xbad; 8668 spdk_blob_set_esnap_bs_dev(blob, bs_dev, bs_op_complete, NULL); 8669 poll_threads(); 8670 CU_ASSERT(g_bserrno == 0); 8671 CU_ASSERT(!destroyed1); 8672 CU_ASSERT(destroyed2); 8673 SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL); 8674 esnap_dev = (struct ut_esnap_dev *)blob->back_bs_dev; 8675 CU_ASSERT(strcmp(esnap_dev->ut_opts.name, "esnap1a") == 0); 8676 8677 /* Clean up */ 8678 set_thread(0); 8679 spdk_bs_free_io_channel(ch0); 8680 set_thread(1); 8681 spdk_bs_free_io_channel(ch1); 8682 set_thread(start_thread); 8683 g_bserrno = 0xbad; 8684 spdk_blob_close(blob, bs_op_complete, NULL); 8685 poll_threads(); 8686 CU_ASSERT(g_bserrno == 0); 8687 } 8688 8689 static bool g_blob_is_degraded; 8690 static int g_blob_is_degraded_called; 8691 8692 static bool 8693 _blob_is_degraded(struct spdk_bs_dev *dev) 8694 { 8695 g_blob_is_degraded_called++; 8696 return g_blob_is_degraded; 8697 } 8698 8699 static void 8700 blob_is_degraded(void) 8701 { 8702 struct spdk_bs_dev bs_is_degraded_null = { 0 }; 8703 struct spdk_bs_dev bs_is_degraded = { .is_degraded = _blob_is_degraded }; 8704 8705 /* No back_bs_dev, no bs->dev->is_degraded */ 8706 g_blob_is_degraded_called = 0; 8707 CU_ASSERT(!spdk_blob_is_degraded(g_blob)); 8708 CU_ASSERT(g_blob_is_degraded_called == 0); 8709 8710 /* No back_bs_dev, blobstore device degraded */ 8711 g_bs->dev->is_degraded = _blob_is_degraded; 8712 g_blob_is_degraded_called = 0; 8713 g_blob_is_degraded = true; 8714 CU_ASSERT(spdk_blob_is_degraded(g_blob)); 8715 CU_ASSERT(g_blob_is_degraded_called == 1); 8716 8717 /* No back_bs_dev, blobstore device not degraded */ 8718 g_bs->dev->is_degraded = _blob_is_degraded; 8719 g_blob_is_degraded_called = 0; 8720 g_blob_is_degraded = false; 8721 CU_ASSERT(!spdk_blob_is_degraded(g_blob)); 8722 CU_ASSERT(g_blob_is_degraded_called == 1); 8723 8724 /* back_bs_dev does not define is_degraded, no bs->dev->is_degraded */ 8725 g_bs->dev->is_degraded = NULL; 8726 g_blob->back_bs_dev = &bs_is_degraded_null; 8727 g_blob_is_degraded_called = 0; 8728 g_blob_is_degraded = false; 8729 CU_ASSERT(!spdk_blob_is_degraded(g_blob)); 8730 CU_ASSERT(g_blob_is_degraded_called == 0); 8731 8732 /* back_bs_dev is not degraded, no bs->dev->is_degraded */ 8733 g_bs->dev->is_degraded = NULL; 8734 g_blob->back_bs_dev = &bs_is_degraded; 8735 g_blob_is_degraded_called = 0; 8736 g_blob_is_degraded = false; 8737 CU_ASSERT(!spdk_blob_is_degraded(g_blob)); 8738 CU_ASSERT(g_blob_is_degraded_called == 1); 8739 8740 /* back_bs_dev is degraded, no bs->dev->is_degraded */ 8741 g_bs->dev->is_degraded = NULL; 8742 g_blob->back_bs_dev = &bs_is_degraded; 8743 g_blob_is_degraded_called = 0; 8744 g_blob_is_degraded = true; 8745 CU_ASSERT(spdk_blob_is_degraded(g_blob)); 8746 CU_ASSERT(g_blob_is_degraded_called == 1); 8747 8748 /* back_bs_dev is not degraded, blobstore device is not degraded */ 8749 g_bs->dev->is_degraded = _blob_is_degraded; 8750 g_blob->back_bs_dev = &bs_is_degraded; 8751 g_blob_is_degraded_called = 0; 8752 g_blob_is_degraded = false; 8753 CU_ASSERT(!spdk_blob_is_degraded(g_blob)); 8754 CU_ASSERT(g_blob_is_degraded_called == 2); 8755 8756 g_blob->back_bs_dev = NULL; 8757 } 8758 8759 static void 8760 suite_bs_setup(void) 8761 { 8762 struct spdk_bs_dev *dev; 8763 8764 dev = init_dev(); 8765 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 8766 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 8767 poll_threads(); 8768 CU_ASSERT(g_bserrno == 0); 8769 CU_ASSERT(g_bs != NULL); 8770 } 8771 8772 static void 8773 suite_esnap_bs_setup(void) 8774 { 8775 struct spdk_bs_dev *dev; 8776 struct spdk_bs_opts bs_opts; 8777 8778 dev = init_dev(); 8779 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 8780 spdk_bs_opts_init(&bs_opts, sizeof(bs_opts)); 8781 bs_opts.cluster_sz = 16 * 1024; 8782 bs_opts.esnap_bs_dev_create = ut_esnap_create; 8783 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 8784 poll_threads(); 8785 CU_ASSERT(g_bserrno == 0); 8786 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 8787 } 8788 8789 static void 8790 suite_bs_cleanup(void) 8791 { 8792 if (g_bs != NULL) { 8793 spdk_bs_unload(g_bs, bs_op_complete, NULL); 8794 poll_threads(); 8795 CU_ASSERT(g_bserrno == 0); 8796 g_bs = NULL; 8797 } 8798 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 8799 } 8800 8801 static struct spdk_blob * 8802 ut_blob_create_and_open(struct spdk_blob_store *bs, struct spdk_blob_opts *blob_opts) 8803 { 8804 struct spdk_blob *blob; 8805 struct spdk_blob_opts create_blob_opts; 8806 spdk_blob_id blobid; 8807 8808 if (blob_opts == NULL) { 8809 ut_spdk_blob_opts_init(&create_blob_opts); 8810 blob_opts = &create_blob_opts; 8811 } 8812 8813 spdk_bs_create_blob_ext(bs, blob_opts, blob_op_with_id_complete, NULL); 8814 poll_threads(); 8815 CU_ASSERT(g_bserrno == 0); 8816 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 8817 blobid = g_blobid; 8818 g_blobid = -1; 8819 8820 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 8821 poll_threads(); 8822 CU_ASSERT(g_bserrno == 0); 8823 CU_ASSERT(g_blob != NULL); 8824 blob = g_blob; 8825 8826 g_blob = NULL; 8827 g_bserrno = -1; 8828 8829 return blob; 8830 } 8831 8832 static void 8833 ut_blob_close_and_delete(struct spdk_blob_store *bs, struct spdk_blob *blob) 8834 { 8835 spdk_blob_id blobid = spdk_blob_get_id(blob); 8836 8837 spdk_blob_close(blob, blob_op_complete, NULL); 8838 poll_threads(); 8839 CU_ASSERT(g_bserrno == 0); 8840 g_blob = NULL; 8841 8842 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 8843 poll_threads(); 8844 CU_ASSERT(g_bserrno == 0); 8845 g_bserrno = -1; 8846 } 8847 8848 static void 8849 suite_blob_setup(void) 8850 { 8851 suite_bs_setup(); 8852 CU_ASSERT(g_bs != NULL); 8853 8854 g_blob = ut_blob_create_and_open(g_bs, NULL); 8855 CU_ASSERT(g_blob != NULL); 8856 } 8857 8858 static void 8859 suite_blob_cleanup(void) 8860 { 8861 ut_blob_close_and_delete(g_bs, g_blob); 8862 CU_ASSERT(g_blob == NULL); 8863 8864 suite_bs_cleanup(); 8865 CU_ASSERT(g_bs == NULL); 8866 } 8867 8868 static int 8869 ut_setup_config_nocopy_noextent(void) 8870 { 8871 g_dev_copy_enabled = false; 8872 g_use_extent_table = false; 8873 8874 return 0; 8875 } 8876 8877 static int 8878 ut_setup_config_nocopy_extent(void) 8879 { 8880 g_dev_copy_enabled = false; 8881 g_use_extent_table = true; 8882 8883 return 0; 8884 } 8885 8886 static int 8887 ut_setup_config_copy_noextent(void) 8888 { 8889 g_dev_copy_enabled = true; 8890 g_use_extent_table = false; 8891 8892 return 0; 8893 } 8894 8895 static int 8896 ut_setup_config_copy_extent(void) 8897 { 8898 g_dev_copy_enabled = true; 8899 g_use_extent_table = true; 8900 8901 return 0; 8902 } 8903 8904 struct ut_config { 8905 const char *suffix; 8906 CU_InitializeFunc setup_cb; 8907 }; 8908 8909 int 8910 main(int argc, char **argv) 8911 { 8912 CU_pSuite suite, suite_bs, suite_blob, suite_esnap_bs; 8913 unsigned int i, num_failures; 8914 char suite_name[4096]; 8915 struct ut_config *config; 8916 struct ut_config configs[] = { 8917 {"nocopy_noextent", ut_setup_config_nocopy_noextent}, 8918 {"nocopy_extent", ut_setup_config_nocopy_extent}, 8919 {"copy_noextent", ut_setup_config_copy_noextent}, 8920 {"copy_extent", ut_setup_config_copy_extent}, 8921 }; 8922 8923 CU_initialize_registry(); 8924 8925 for (i = 0; i < SPDK_COUNTOF(configs); ++i) { 8926 config = &configs[i]; 8927 8928 snprintf(suite_name, sizeof(suite_name), "blob_%s", config->suffix); 8929 suite = CU_add_suite(suite_name, config->setup_cb, NULL); 8930 8931 snprintf(suite_name, sizeof(suite_name), "blob_bs_%s", config->suffix); 8932 suite_bs = CU_add_suite_with_setup_and_teardown(suite_name, config->setup_cb, NULL, 8933 suite_bs_setup, suite_bs_cleanup); 8934 8935 snprintf(suite_name, sizeof(suite_name), "blob_blob_%s", config->suffix); 8936 suite_blob = CU_add_suite_with_setup_and_teardown(suite_name, config->setup_cb, NULL, 8937 suite_blob_setup, suite_blob_cleanup); 8938 8939 snprintf(suite_name, sizeof(suite_name), "blob_esnap_bs_%s", config->suffix); 8940 suite_esnap_bs = CU_add_suite_with_setup_and_teardown(suite_name, config->setup_cb, NULL, 8941 suite_esnap_bs_setup, 8942 suite_bs_cleanup); 8943 8944 CU_ADD_TEST(suite, blob_init); 8945 CU_ADD_TEST(suite_bs, blob_open); 8946 CU_ADD_TEST(suite_bs, blob_create); 8947 CU_ADD_TEST(suite_bs, blob_create_loop); 8948 CU_ADD_TEST(suite_bs, blob_create_fail); 8949 CU_ADD_TEST(suite_bs, blob_create_internal); 8950 CU_ADD_TEST(suite_bs, blob_create_zero_extent); 8951 CU_ADD_TEST(suite, blob_thin_provision); 8952 CU_ADD_TEST(suite_bs, blob_snapshot); 8953 CU_ADD_TEST(suite_bs, blob_clone); 8954 CU_ADD_TEST(suite_bs, blob_inflate); 8955 CU_ADD_TEST(suite_bs, blob_delete); 8956 CU_ADD_TEST(suite_bs, blob_resize_test); 8957 CU_ADD_TEST(suite, blob_read_only); 8958 CU_ADD_TEST(suite_bs, channel_ops); 8959 CU_ADD_TEST(suite_bs, blob_super); 8960 CU_ADD_TEST(suite_blob, blob_write); 8961 CU_ADD_TEST(suite_blob, blob_read); 8962 CU_ADD_TEST(suite_blob, blob_rw_verify); 8963 CU_ADD_TEST(suite_bs, blob_rw_verify_iov); 8964 CU_ADD_TEST(suite_blob, blob_rw_verify_iov_nomem); 8965 CU_ADD_TEST(suite_blob, blob_rw_iov_read_only); 8966 CU_ADD_TEST(suite_bs, blob_unmap); 8967 CU_ADD_TEST(suite_bs, blob_iter); 8968 CU_ADD_TEST(suite_blob, blob_xattr); 8969 CU_ADD_TEST(suite_bs, blob_parse_md); 8970 CU_ADD_TEST(suite, bs_load); 8971 CU_ADD_TEST(suite_bs, bs_load_pending_removal); 8972 CU_ADD_TEST(suite, bs_load_custom_cluster_size); 8973 CU_ADD_TEST(suite, bs_load_after_failed_grow); 8974 CU_ADD_TEST(suite_bs, bs_unload); 8975 CU_ADD_TEST(suite, bs_cluster_sz); 8976 CU_ADD_TEST(suite_bs, bs_usable_clusters); 8977 CU_ADD_TEST(suite, bs_resize_md); 8978 CU_ADD_TEST(suite, bs_destroy); 8979 CU_ADD_TEST(suite, bs_type); 8980 CU_ADD_TEST(suite, bs_super_block); 8981 CU_ADD_TEST(suite, bs_test_recover_cluster_count); 8982 CU_ADD_TEST(suite, bs_grow_live); 8983 CU_ADD_TEST(suite, bs_grow_live_no_space); 8984 CU_ADD_TEST(suite, bs_test_grow); 8985 CU_ADD_TEST(suite, blob_serialize_test); 8986 CU_ADD_TEST(suite_bs, blob_crc); 8987 CU_ADD_TEST(suite, super_block_crc); 8988 CU_ADD_TEST(suite_blob, blob_dirty_shutdown); 8989 CU_ADD_TEST(suite_bs, blob_flags); 8990 CU_ADD_TEST(suite_bs, bs_version); 8991 CU_ADD_TEST(suite_bs, blob_set_xattrs_test); 8992 CU_ADD_TEST(suite_bs, blob_thin_prov_alloc); 8993 CU_ADD_TEST(suite_bs, blob_insert_cluster_msg_test); 8994 CU_ADD_TEST(suite_bs, blob_thin_prov_rw); 8995 CU_ADD_TEST(suite, blob_thin_prov_write_count_io); 8996 CU_ADD_TEST(suite_bs, blob_thin_prov_rle); 8997 CU_ADD_TEST(suite_bs, blob_thin_prov_rw_iov); 8998 CU_ADD_TEST(suite, bs_load_iter_test); 8999 CU_ADD_TEST(suite_bs, blob_snapshot_rw); 9000 CU_ADD_TEST(suite_bs, blob_snapshot_rw_iov); 9001 CU_ADD_TEST(suite, blob_relations); 9002 CU_ADD_TEST(suite, blob_relations2); 9003 CU_ADD_TEST(suite, blob_relations3); 9004 CU_ADD_TEST(suite, blobstore_clean_power_failure); 9005 CU_ADD_TEST(suite, blob_delete_snapshot_power_failure); 9006 CU_ADD_TEST(suite, blob_create_snapshot_power_failure); 9007 CU_ADD_TEST(suite_bs, blob_inflate_rw); 9008 CU_ADD_TEST(suite_bs, blob_snapshot_freeze_io); 9009 CU_ADD_TEST(suite_bs, blob_operation_split_rw); 9010 CU_ADD_TEST(suite_bs, blob_operation_split_rw_iov); 9011 CU_ADD_TEST(suite, blob_io_unit); 9012 CU_ADD_TEST(suite, blob_io_unit_compatibility); 9013 CU_ADD_TEST(suite_bs, blob_simultaneous_operations); 9014 CU_ADD_TEST(suite_bs, blob_persist_test); 9015 CU_ADD_TEST(suite_bs, blob_decouple_snapshot); 9016 CU_ADD_TEST(suite_bs, blob_seek_io_unit); 9017 CU_ADD_TEST(suite_esnap_bs, blob_esnap_create); 9018 CU_ADD_TEST(suite_bs, blob_nested_freezes); 9019 CU_ADD_TEST(suite, blob_ext_md_pages); 9020 CU_ADD_TEST(suite, blob_esnap_io_4096_4096); 9021 CU_ADD_TEST(suite, blob_esnap_io_512_512); 9022 CU_ADD_TEST(suite, blob_esnap_io_4096_512); 9023 CU_ADD_TEST(suite, blob_esnap_io_512_4096); 9024 CU_ADD_TEST(suite_esnap_bs, blob_esnap_thread_add_remove); 9025 CU_ADD_TEST(suite_esnap_bs, blob_esnap_clone_snapshot); 9026 CU_ADD_TEST(suite_esnap_bs, blob_esnap_clone_inflate); 9027 CU_ADD_TEST(suite_esnap_bs, blob_esnap_clone_decouple); 9028 CU_ADD_TEST(suite_esnap_bs, blob_esnap_clone_reload); 9029 CU_ADD_TEST(suite_esnap_bs, blob_esnap_hotplug); 9030 CU_ADD_TEST(suite_blob, blob_is_degraded); 9031 } 9032 9033 allocate_threads(2); 9034 set_thread(0); 9035 9036 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 9037 9038 num_failures = spdk_ut_run_tests(argc, argv, NULL); 9039 9040 free(g_dev_buffer); 9041 9042 free_threads(); 9043 9044 return num_failures; 9045 } 9046