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