1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "spdk_cunit.h" 37 #include "spdk/blob.h" 38 #include "spdk/string.h" 39 40 #include "common/lib/test_env.c" 41 #include "../bs_dev_common.c" 42 #include "blob/blobstore.c" 43 #include "blob/request.c" 44 #include "blob/zeroes.c" 45 #include "blob/blob_bs_dev.c" 46 47 struct spdk_blob_store *g_bs; 48 spdk_blob_id g_blobid; 49 struct spdk_blob *g_blob; 50 int g_bserrno; 51 struct spdk_xattr_names *g_names; 52 int g_done; 53 char *g_xattr_names[] = {"first", "second", "third"}; 54 char *g_xattr_values[] = {"one", "two", "three"}; 55 uint64_t g_ctx = 1729; 56 57 bool g_scheduler_delay = false; 58 59 struct scheduled_ops { 60 spdk_thread_fn fn; 61 void *ctx; 62 63 TAILQ_ENTRY(scheduled_ops) ops_queue; 64 }; 65 66 static TAILQ_HEAD(, scheduled_ops) g_scheduled_ops = TAILQ_HEAD_INITIALIZER(g_scheduled_ops); 67 68 struct spdk_bs_super_block_ver1 { 69 uint8_t signature[8]; 70 uint32_t version; 71 uint32_t length; 72 uint32_t clean; /* If there was a clean shutdown, this is 1. */ 73 spdk_blob_id super_blob; 74 75 uint32_t cluster_size; /* In bytes */ 76 77 uint32_t used_page_mask_start; /* Offset from beginning of disk, in pages */ 78 uint32_t used_page_mask_len; /* Count, in pages */ 79 80 uint32_t used_cluster_mask_start; /* Offset from beginning of disk, in pages */ 81 uint32_t used_cluster_mask_len; /* Count, in pages */ 82 83 uint32_t md_start; /* Offset from beginning of disk, in pages */ 84 uint32_t md_len; /* Count, in pages */ 85 86 uint8_t reserved[4036]; 87 uint32_t crc; 88 } __attribute__((packed)); 89 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size"); 90 91 92 static void 93 _get_xattr_value(void *arg, const char *name, 94 const void **value, size_t *value_len) 95 { 96 uint64_t i; 97 98 SPDK_CU_ASSERT_FATAL(value_len != NULL); 99 SPDK_CU_ASSERT_FATAL(value != NULL); 100 CU_ASSERT(arg == &g_ctx) 101 102 for (i = 0; i < sizeof(g_xattr_names); i++) { 103 if (!strcmp(name, g_xattr_names[i])) { 104 *value_len = strlen(g_xattr_values[i]); 105 *value = g_xattr_values[i]; 106 break; 107 } 108 } 109 } 110 111 static void 112 _get_xattr_value_null(void *arg, const char *name, 113 const void **value, size_t *value_len) 114 { 115 SPDK_CU_ASSERT_FATAL(value_len != NULL); 116 SPDK_CU_ASSERT_FATAL(value != NULL); 117 CU_ASSERT(arg == NULL) 118 119 *value_len = 0; 120 *value = NULL; 121 } 122 123 124 static void 125 _bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) 126 { 127 if (g_scheduler_delay) { 128 struct scheduled_ops *ops = calloc(1, sizeof(*ops)); 129 130 SPDK_CU_ASSERT_FATAL(ops != NULL); 131 ops->fn = fn; 132 ops->ctx = ctx; 133 TAILQ_INSERT_TAIL(&g_scheduled_ops, ops, ops_queue); 134 } else { 135 fn(ctx); 136 } 137 } 138 139 #if 0 140 static void 141 _bs_flush_scheduler(void) 142 { 143 struct scheduled_ops *ops; 144 145 while (!TAILQ_EMPTY(&g_scheduled_ops)) { 146 ops = TAILQ_FIRST(&g_scheduled_ops); 147 TAILQ_REMOVE(&g_scheduled_ops, ops, ops_queue); 148 ops->fn(ops->ctx); 149 free(ops); 150 } 151 } 152 #endif 153 154 static void 155 bs_op_complete(void *cb_arg, int bserrno) 156 { 157 g_bserrno = bserrno; 158 } 159 160 static void 161 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 162 int bserrno) 163 { 164 g_bs = bs; 165 g_bserrno = bserrno; 166 } 167 168 static void 169 blob_op_complete(void *cb_arg, int bserrno) 170 { 171 g_bserrno = bserrno; 172 } 173 174 static void 175 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 176 { 177 g_blobid = blobid; 178 g_bserrno = bserrno; 179 } 180 181 static void 182 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 183 { 184 g_blob = blb; 185 g_bserrno = bserrno; 186 } 187 188 static void 189 blob_init(void) 190 { 191 struct spdk_bs_dev *dev; 192 193 dev = init_dev(); 194 195 /* should fail for an unsupported blocklen */ 196 dev->blocklen = 500; 197 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 198 CU_ASSERT(g_bserrno == -EINVAL); 199 200 dev = init_dev(); 201 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 202 CU_ASSERT(g_bserrno == 0); 203 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 204 205 spdk_bs_unload(g_bs, bs_op_complete, NULL); 206 CU_ASSERT(g_bserrno == 0); 207 g_bs = NULL; 208 } 209 210 static void 211 blob_super(void) 212 { 213 struct spdk_blob_store *bs; 214 struct spdk_bs_dev *dev; 215 spdk_blob_id blobid; 216 217 dev = init_dev(); 218 219 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 220 CU_ASSERT(g_bserrno == 0); 221 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 222 bs = g_bs; 223 224 /* Get the super blob without having set one */ 225 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 226 CU_ASSERT(g_bserrno == -ENOENT); 227 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 228 229 /* Create a blob */ 230 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 231 CU_ASSERT(g_bserrno == 0); 232 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 233 blobid = g_blobid; 234 235 /* Set the blob as the super blob */ 236 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 237 CU_ASSERT(g_bserrno == 0); 238 239 /* Get the super blob */ 240 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 241 CU_ASSERT(g_bserrno == 0); 242 CU_ASSERT(blobid == g_blobid); 243 244 spdk_bs_unload(g_bs, bs_op_complete, NULL); 245 CU_ASSERT(g_bserrno == 0); 246 g_bs = NULL; 247 } 248 249 static void 250 blob_open(void) 251 { 252 struct spdk_blob_store *bs; 253 struct spdk_bs_dev *dev; 254 struct spdk_blob *blob; 255 spdk_blob_id blobid, blobid2; 256 257 dev = init_dev(); 258 259 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 260 CU_ASSERT(g_bserrno == 0); 261 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 262 bs = g_bs; 263 264 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 265 CU_ASSERT(g_bserrno == 0); 266 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 267 blobid = g_blobid; 268 269 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 270 CU_ASSERT(g_bserrno == 0); 271 CU_ASSERT(g_blob != NULL); 272 blob = g_blob; 273 274 blobid2 = spdk_blob_get_id(blob); 275 CU_ASSERT(blobid == blobid2); 276 277 /* Try to open file again. It should return success. */ 278 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 279 CU_ASSERT(g_bserrno == 0); 280 CU_ASSERT(blob == g_blob); 281 282 spdk_blob_close(blob, blob_op_complete, NULL); 283 CU_ASSERT(g_bserrno == 0); 284 285 /* 286 * Close the file a second time, releasing the second reference. This 287 * should succeed. 288 */ 289 blob = g_blob; 290 spdk_blob_close(blob, blob_op_complete, NULL); 291 CU_ASSERT(g_bserrno == 0); 292 293 /* 294 * Try to open file again. It should succeed. This tests the case 295 * where the file is opened, closed, then re-opened again. 296 */ 297 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 298 CU_ASSERT(g_bserrno == 0); 299 CU_ASSERT(g_blob != NULL); 300 blob = g_blob; 301 302 spdk_blob_close(blob, blob_op_complete, NULL); 303 CU_ASSERT(g_bserrno == 0); 304 305 spdk_bs_unload(g_bs, bs_op_complete, NULL); 306 CU_ASSERT(g_bserrno == 0); 307 g_bs = NULL; 308 } 309 310 static void 311 blob_create(void) 312 { 313 struct spdk_blob_store *bs; 314 struct spdk_bs_dev *dev; 315 struct spdk_blob *blob; 316 struct spdk_blob_opts opts; 317 spdk_blob_id blobid; 318 319 dev = init_dev(); 320 321 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 322 CU_ASSERT(g_bserrno == 0); 323 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 324 bs = g_bs; 325 326 /* Create blob with 10 clusters */ 327 328 spdk_blob_opts_init(&opts); 329 opts.num_clusters = 10; 330 331 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 332 CU_ASSERT(g_bserrno == 0); 333 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 334 blobid = g_blobid; 335 336 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 337 CU_ASSERT(g_bserrno == 0); 338 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 339 blob = g_blob; 340 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 341 342 spdk_blob_close(blob, blob_op_complete, NULL); 343 CU_ASSERT(g_bserrno == 0); 344 345 /* Create blob with 0 clusters */ 346 347 spdk_blob_opts_init(&opts); 348 opts.num_clusters = 0; 349 350 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 351 CU_ASSERT(g_bserrno == 0); 352 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 353 blobid = g_blobid; 354 355 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 356 CU_ASSERT(g_bserrno == 0); 357 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 358 blob = g_blob; 359 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 360 361 spdk_blob_close(blob, blob_op_complete, NULL); 362 CU_ASSERT(g_bserrno == 0); 363 364 /* Create blob with default options (opts == NULL) */ 365 366 spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL); 367 CU_ASSERT(g_bserrno == 0); 368 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 369 blobid = g_blobid; 370 371 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 372 CU_ASSERT(g_bserrno == 0); 373 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 374 blob = g_blob; 375 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 376 377 spdk_blob_close(blob, blob_op_complete, NULL); 378 CU_ASSERT(g_bserrno == 0); 379 380 /* Try to create blob with size larger than blobstore */ 381 382 spdk_blob_opts_init(&opts); 383 opts.num_clusters = bs->total_clusters + 1; 384 385 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 386 CU_ASSERT(g_bserrno == -ENOSPC); 387 388 spdk_bs_unload(g_bs, bs_op_complete, NULL); 389 CU_ASSERT(g_bserrno == 0); 390 g_bs = NULL; 391 392 } 393 394 static void 395 blob_create_internal(void) 396 { 397 struct spdk_blob_store *bs; 398 struct spdk_bs_dev *dev; 399 struct spdk_blob *blob; 400 struct spdk_blob_opts opts; 401 struct spdk_blob_xattr_opts internal_xattrs; 402 const void *value; 403 size_t value_len; 404 spdk_blob_id blobid; 405 int rc; 406 407 dev = init_dev(); 408 409 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 410 CU_ASSERT(g_bserrno == 0); 411 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 412 bs = g_bs; 413 414 /* Create blob with custom xattrs */ 415 416 spdk_blob_opts_init(&opts); 417 _spdk_blob_xattrs_init(&internal_xattrs); 418 internal_xattrs.count = 3; 419 internal_xattrs.names = g_xattr_names; 420 internal_xattrs.get_value = _get_xattr_value; 421 internal_xattrs.ctx = &g_ctx; 422 423 _spdk_bs_create_blob(bs, &opts, &internal_xattrs, blob_op_with_id_complete, NULL); 424 CU_ASSERT(g_bserrno == 0); 425 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 426 blobid = g_blobid; 427 428 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 429 CU_ASSERT(g_bserrno == 0); 430 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 431 blob = g_blob; 432 433 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len, true); 434 CU_ASSERT(rc == 0); 435 SPDK_CU_ASSERT_FATAL(value != NULL); 436 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 437 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 438 439 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len, true); 440 CU_ASSERT(rc == 0); 441 SPDK_CU_ASSERT_FATAL(value != NULL); 442 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 443 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 444 445 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len, true); 446 CU_ASSERT(rc == 0); 447 SPDK_CU_ASSERT_FATAL(value != NULL); 448 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 449 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 450 451 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 452 CU_ASSERT(rc != 0); 453 454 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 455 CU_ASSERT(rc != 0); 456 457 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 458 CU_ASSERT(rc != 0); 459 460 spdk_blob_close(blob, blob_op_complete, NULL); 461 CU_ASSERT(g_bserrno == 0); 462 463 /* Create blob with NULL internal options */ 464 465 _spdk_bs_create_blob(bs, NULL, NULL, blob_op_with_id_complete, NULL); 466 CU_ASSERT(g_bserrno == 0); 467 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 468 blobid = g_blobid; 469 470 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 471 CU_ASSERT(g_bserrno == 0); 472 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 473 CU_ASSERT(TAILQ_FIRST(&g_blob->xattrs_internal) == NULL); 474 475 blob = g_blob; 476 477 spdk_blob_close(blob, blob_op_complete, NULL); 478 CU_ASSERT(g_bserrno == 0); 479 480 spdk_bs_unload(g_bs, bs_op_complete, NULL); 481 CU_ASSERT(g_bserrno == 0); 482 g_bs = NULL; 483 484 } 485 486 static void 487 blob_thin_provision(void) 488 { 489 struct spdk_blob_store *bs; 490 struct spdk_bs_dev *dev; 491 struct spdk_blob *blob; 492 struct spdk_blob_opts opts; 493 struct spdk_bs_opts bs_opts; 494 spdk_blob_id blobid; 495 496 dev = init_dev(); 497 spdk_bs_opts_init(&bs_opts); 498 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 499 500 /* Initialize a new blob store */ 501 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 502 CU_ASSERT(g_bserrno == 0); 503 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 504 505 bs = g_bs; 506 507 /* Create blob with thin provisioning enabled */ 508 509 spdk_blob_opts_init(&opts); 510 opts.thin_provision = true; 511 opts.num_clusters = 10; 512 513 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 514 CU_ASSERT(g_bserrno == 0); 515 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 516 blobid = g_blobid; 517 518 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 519 CU_ASSERT(g_bserrno == 0); 520 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 521 blob = g_blob; 522 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 523 524 spdk_blob_close(blob, blob_op_complete, NULL); 525 CU_ASSERT(g_bserrno == 0); 526 527 /* Do not shut down cleanly. This makes sure that when we load again 528 * and try to recover a valid used_cluster map, that blobstore will 529 * ignore clusters with index 0 since these are unallocated clusters. 530 */ 531 532 /* Load an existing blob store and check if invalid_flags is set */ 533 dev = init_dev(); 534 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 535 spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL); 536 CU_ASSERT(g_bserrno == 0); 537 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 538 539 bs = g_bs; 540 541 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 542 CU_ASSERT(g_bserrno == 0); 543 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 544 blob = g_blob; 545 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 546 547 spdk_blob_close(blob, blob_op_complete, NULL); 548 CU_ASSERT(g_bserrno == 0); 549 550 spdk_bs_unload(g_bs, bs_op_complete, NULL); 551 CU_ASSERT(g_bserrno == 0); 552 g_bs = NULL; 553 } 554 555 static void 556 blob_snapshot(void) 557 { 558 struct spdk_blob_store *bs; 559 struct spdk_bs_dev *dev; 560 struct spdk_blob *blob; 561 struct spdk_blob *snapshot, *snapshot2; 562 struct spdk_blob_bs_dev *blob_bs_dev; 563 struct spdk_blob_opts opts; 564 struct spdk_blob_xattr_opts xattrs; 565 spdk_blob_id blobid; 566 spdk_blob_id snapshotid; 567 const void *value; 568 size_t value_len; 569 int rc; 570 571 dev = init_dev(); 572 573 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 574 CU_ASSERT(g_bserrno == 0); 575 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 576 bs = g_bs; 577 578 /* Create blob with 10 clusters */ 579 spdk_blob_opts_init(&opts); 580 opts.num_clusters = 10; 581 582 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 583 CU_ASSERT(g_bserrno == 0); 584 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 585 blobid = g_blobid; 586 587 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 588 CU_ASSERT(g_bserrno == 0); 589 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 590 blob = g_blob; 591 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 592 593 /* Create snapshot from blob */ 594 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 595 CU_ASSERT(g_bserrno == 0); 596 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 597 snapshotid = g_blobid; 598 599 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 600 CU_ASSERT(g_bserrno == 0); 601 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 602 snapshot = g_blob; 603 CU_ASSERT(snapshot->data_ro == true) 604 CU_ASSERT(snapshot->md_ro == true) 605 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10) 606 607 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 608 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 609 CU_ASSERT(spdk_mem_all_zero(blob->active.clusters, 610 blob->active.num_clusters * sizeof(blob->active.clusters[0]))); 611 612 /* Try to create snapshot from clone with xattrs */ 613 xattrs.names = g_xattr_names; 614 xattrs.get_value = _get_xattr_value; 615 xattrs.count = 3; 616 xattrs.ctx = &g_ctx; 617 spdk_bs_create_snapshot(bs, blobid, &xattrs, blob_op_with_id_complete, NULL); 618 CU_ASSERT(g_bserrno == 0); 619 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 620 blobid = g_blobid; 621 622 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 623 CU_ASSERT(g_bserrno == 0); 624 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 625 snapshot2 = g_blob; 626 CU_ASSERT(snapshot2->data_ro == true) 627 CU_ASSERT(snapshot2->md_ro == true) 628 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 10) 629 630 /* Confirm that blob is backed by snapshot2 and snapshot2 is backed by snapshot */ 631 CU_ASSERT(snapshot->back_bs_dev == NULL); 632 SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL); 633 SPDK_CU_ASSERT_FATAL(snapshot2->back_bs_dev != NULL); 634 635 blob_bs_dev = (struct spdk_blob_bs_dev *)blob->back_bs_dev; 636 CU_ASSERT(blob_bs_dev->blob == snapshot2); 637 638 blob_bs_dev = (struct spdk_blob_bs_dev *)snapshot2->back_bs_dev; 639 CU_ASSERT(blob_bs_dev->blob == snapshot); 640 641 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[0], &value, &value_len); 642 CU_ASSERT(rc == 0); 643 SPDK_CU_ASSERT_FATAL(value != NULL); 644 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 645 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 646 647 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[1], &value, &value_len); 648 CU_ASSERT(rc == 0); 649 SPDK_CU_ASSERT_FATAL(value != NULL); 650 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 651 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 652 653 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[2], &value, &value_len); 654 CU_ASSERT(rc == 0); 655 SPDK_CU_ASSERT_FATAL(value != NULL); 656 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 657 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 658 659 /* Try to create snapshot from snapshot */ 660 spdk_bs_create_snapshot(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 661 CU_ASSERT(g_bserrno == -EINVAL); 662 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 663 664 spdk_blob_close(blob, blob_op_complete, NULL); 665 CU_ASSERT(g_bserrno == 0); 666 667 spdk_blob_close(snapshot, blob_op_complete, NULL); 668 CU_ASSERT(g_bserrno == 0); 669 670 spdk_blob_close(snapshot2, blob_op_complete, NULL); 671 CU_ASSERT(g_bserrno == 0); 672 673 spdk_bs_unload(g_bs, bs_op_complete, NULL); 674 CU_ASSERT(g_bserrno == 0); 675 g_bs = NULL; 676 } 677 678 static void 679 blob_clone(void) 680 { 681 struct spdk_blob_store *bs; 682 struct spdk_bs_dev *dev; 683 struct spdk_blob_opts opts; 684 struct spdk_blob *blob, *snapshot, *clone; 685 spdk_blob_id blobid, cloneid, snapshotid; 686 struct spdk_blob_xattr_opts xattrs; 687 const void *value; 688 size_t value_len; 689 int rc; 690 691 dev = init_dev(); 692 693 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 694 CU_ASSERT(g_bserrno == 0); 695 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 696 bs = g_bs; 697 698 /* Create blob with 10 clusters */ 699 700 spdk_blob_opts_init(&opts); 701 opts.num_clusters = 10; 702 703 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 704 CU_ASSERT(g_bserrno == 0); 705 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 706 blobid = g_blobid; 707 708 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 709 CU_ASSERT(g_bserrno == 0); 710 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 711 blob = g_blob; 712 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 713 714 /* Create snapshot */ 715 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 716 CU_ASSERT(g_bserrno == 0); 717 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 718 snapshotid = g_blobid; 719 720 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 721 CU_ASSERT(g_bserrno == 0); 722 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 723 snapshot = g_blob; 724 CU_ASSERT(snapshot->data_ro == true) 725 CU_ASSERT(snapshot->md_ro == true) 726 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 727 728 spdk_blob_close(snapshot, blob_op_complete, NULL); 729 CU_ASSERT(g_bserrno == 0); 730 731 /* Create clone from snapshot with xattrs */ 732 xattrs.names = g_xattr_names; 733 xattrs.get_value = _get_xattr_value; 734 xattrs.count = 3; 735 xattrs.ctx = &g_ctx; 736 737 spdk_bs_create_clone(bs, snapshotid, &xattrs, blob_op_with_id_complete, NULL); 738 CU_ASSERT(g_bserrno == 0); 739 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 740 cloneid = g_blobid; 741 742 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 743 CU_ASSERT(g_bserrno == 0); 744 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 745 clone = g_blob; 746 CU_ASSERT(clone->data_ro == false) 747 CU_ASSERT(clone->md_ro == false) 748 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 749 750 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[0], &value, &value_len); 751 CU_ASSERT(rc == 0); 752 SPDK_CU_ASSERT_FATAL(value != NULL); 753 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 754 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 755 756 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[1], &value, &value_len); 757 CU_ASSERT(rc == 0); 758 SPDK_CU_ASSERT_FATAL(value != NULL); 759 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 760 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 761 762 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[2], &value, &value_len); 763 CU_ASSERT(rc == 0); 764 SPDK_CU_ASSERT_FATAL(value != NULL); 765 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 766 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 767 768 769 spdk_blob_close(clone, blob_op_complete, NULL); 770 CU_ASSERT(g_bserrno == 0); 771 772 /* Try to create clone from not read only blob */ 773 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 774 CU_ASSERT(g_bserrno == -EINVAL); 775 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 776 777 /* Mark blob as read only */ 778 spdk_blob_set_read_only(blob); 779 spdk_blob_sync_md(blob, blob_op_complete, NULL); 780 CU_ASSERT(g_bserrno == 0); 781 782 /* Create clone from read only blob */ 783 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 784 CU_ASSERT(g_bserrno == 0); 785 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 786 cloneid = g_blobid; 787 788 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 789 CU_ASSERT(g_bserrno == 0); 790 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 791 clone = g_blob; 792 CU_ASSERT(clone->data_ro == false) 793 CU_ASSERT(clone->md_ro == false) 794 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 795 796 spdk_blob_close(clone, blob_op_complete, NULL); 797 CU_ASSERT(g_bserrno == 0); 798 799 spdk_blob_close(blob, blob_op_complete, NULL); 800 CU_ASSERT(g_bserrno == 0); 801 802 spdk_bs_unload(g_bs, bs_op_complete, NULL); 803 CU_ASSERT(g_bserrno == 0); 804 g_bs = NULL; 805 806 } 807 808 static void 809 blob_delete(void) 810 { 811 struct spdk_blob_store *bs; 812 struct spdk_bs_dev *dev; 813 spdk_blob_id blobid; 814 815 dev = init_dev(); 816 817 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 818 CU_ASSERT(g_bserrno == 0); 819 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 820 bs = g_bs; 821 822 /* Create a blob and then delete it. */ 823 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 824 CU_ASSERT(g_bserrno == 0); 825 CU_ASSERT(g_blobid > 0); 826 blobid = g_blobid; 827 828 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 829 CU_ASSERT(g_bserrno == 0); 830 831 /* Try to open the blob */ 832 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 833 CU_ASSERT(g_bserrno == -ENOENT); 834 835 spdk_bs_unload(g_bs, bs_op_complete, NULL); 836 CU_ASSERT(g_bserrno == 0); 837 g_bs = NULL; 838 } 839 840 static void 841 blob_resize(void) 842 { 843 struct spdk_blob_store *bs; 844 struct spdk_bs_dev *dev; 845 struct spdk_blob *blob; 846 spdk_blob_id blobid; 847 uint64_t free_clusters; 848 849 dev = init_dev(); 850 851 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 852 CU_ASSERT(g_bserrno == 0); 853 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 854 bs = g_bs; 855 free_clusters = spdk_bs_free_cluster_count(bs); 856 857 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 858 CU_ASSERT(g_bserrno == 0); 859 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 860 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 861 blobid = g_blobid; 862 863 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 864 CU_ASSERT(g_bserrno == 0); 865 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 866 blob = g_blob; 867 868 /* Confirm that resize fails if blob is marked read-only. */ 869 blob->md_ro = true; 870 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 871 CU_ASSERT(g_bserrno == -EPERM); 872 blob->md_ro = false; 873 874 /* The blob started at 0 clusters. Resize it to be 5. */ 875 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 876 CU_ASSERT(g_bserrno == 0); 877 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 878 879 /* Shrink the blob to 3 clusters. This will not actually release 880 * the old clusters until the blob is synced. 881 */ 882 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 883 CU_ASSERT(g_bserrno == 0); 884 /* Verify there are still 5 clusters in use */ 885 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 886 887 spdk_blob_sync_md(blob, blob_op_complete, NULL); 888 CU_ASSERT(g_bserrno == 0); 889 /* Now there are only 3 clusters in use */ 890 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 891 892 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 893 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 894 CU_ASSERT(g_bserrno == 0); 895 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 896 897 /* Try to resize the blob to size larger than blobstore. */ 898 spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL); 899 CU_ASSERT(g_bserrno == -ENOSPC); 900 901 spdk_blob_close(blob, blob_op_complete, NULL); 902 CU_ASSERT(g_bserrno == 0); 903 904 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 905 CU_ASSERT(g_bserrno == 0); 906 907 spdk_bs_unload(g_bs, bs_op_complete, NULL); 908 CU_ASSERT(g_bserrno == 0); 909 g_bs = NULL; 910 } 911 912 static void 913 blob_read_only(void) 914 { 915 struct spdk_blob_store *bs; 916 struct spdk_bs_dev *dev; 917 struct spdk_blob *blob; 918 struct spdk_bs_opts opts; 919 spdk_blob_id blobid; 920 int rc; 921 922 dev = init_dev(); 923 spdk_bs_opts_init(&opts); 924 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 925 926 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 927 CU_ASSERT(g_bserrno == 0); 928 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 929 bs = g_bs; 930 931 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 932 CU_ASSERT(g_bserrno == 0); 933 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 934 blobid = g_blobid; 935 936 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 937 CU_ASSERT(g_bserrno == 0); 938 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 939 blob = g_blob; 940 941 rc = spdk_blob_set_read_only(blob); 942 CU_ASSERT(rc == 0); 943 944 CU_ASSERT(blob->data_ro == false); 945 CU_ASSERT(blob->md_ro == false); 946 947 spdk_blob_sync_md(blob, bs_op_complete, NULL); 948 949 CU_ASSERT(blob->data_ro == true); 950 CU_ASSERT(blob->md_ro == true); 951 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 952 953 spdk_blob_close(blob, blob_op_complete, NULL); 954 CU_ASSERT(g_bserrno == 0); 955 956 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 957 CU_ASSERT(g_bserrno == 0); 958 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 959 blob = g_blob; 960 961 CU_ASSERT(blob->data_ro == true); 962 CU_ASSERT(blob->md_ro == true); 963 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 964 965 spdk_blob_close(blob, blob_op_complete, NULL); 966 CU_ASSERT(g_bserrno == 0); 967 968 spdk_bs_unload(g_bs, bs_op_complete, NULL); 969 CU_ASSERT(g_bserrno == 0); 970 g_bs = NULL; 971 g_blob = NULL; 972 g_blobid = 0; 973 974 /* Load an existing blob store */ 975 dev = init_dev(); 976 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 977 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 978 CU_ASSERT(g_bserrno == 0); 979 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 980 981 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 982 CU_ASSERT(g_bserrno == 0); 983 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 984 blob = g_blob; 985 986 CU_ASSERT(blob->data_ro == true); 987 CU_ASSERT(blob->md_ro == true); 988 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 989 990 spdk_blob_close(blob, blob_op_complete, NULL); 991 CU_ASSERT(g_bserrno == 0); 992 993 spdk_bs_unload(g_bs, bs_op_complete, NULL); 994 CU_ASSERT(g_bserrno == 0); 995 996 } 997 998 static void 999 channel_ops(void) 1000 { 1001 struct spdk_blob_store *bs; 1002 struct spdk_bs_dev *dev; 1003 struct spdk_io_channel *channel; 1004 1005 dev = init_dev(); 1006 1007 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1008 CU_ASSERT(g_bserrno == 0); 1009 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1010 bs = g_bs; 1011 1012 channel = spdk_bs_alloc_io_channel(bs); 1013 CU_ASSERT(channel != NULL); 1014 1015 spdk_bs_free_io_channel(channel); 1016 1017 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1018 CU_ASSERT(g_bserrno == 0); 1019 g_bs = NULL; 1020 } 1021 1022 static void 1023 blob_write(void) 1024 { 1025 struct spdk_blob_store *bs; 1026 struct spdk_bs_dev *dev; 1027 struct spdk_blob *blob; 1028 struct spdk_io_channel *channel; 1029 spdk_blob_id blobid; 1030 uint64_t pages_per_cluster; 1031 uint8_t payload[10 * 4096]; 1032 1033 dev = init_dev(); 1034 1035 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1036 CU_ASSERT(g_bserrno == 0); 1037 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1038 bs = g_bs; 1039 1040 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1041 1042 channel = spdk_bs_alloc_io_channel(bs); 1043 CU_ASSERT(channel != NULL); 1044 1045 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1046 CU_ASSERT(g_bserrno == 0); 1047 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1048 blobid = g_blobid; 1049 1050 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1051 CU_ASSERT(g_bserrno == 0); 1052 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1053 blob = g_blob; 1054 1055 /* Write to a blob with 0 size */ 1056 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1057 CU_ASSERT(g_bserrno == -EINVAL); 1058 1059 /* Resize the blob */ 1060 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1061 CU_ASSERT(g_bserrno == 0); 1062 1063 /* Confirm that write fails if blob is marked read-only. */ 1064 blob->data_ro = true; 1065 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1066 CU_ASSERT(g_bserrno == -EPERM); 1067 blob->data_ro = false; 1068 1069 /* Write to the blob */ 1070 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1071 CU_ASSERT(g_bserrno == 0); 1072 1073 /* Write starting beyond the end */ 1074 spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1075 NULL); 1076 CU_ASSERT(g_bserrno == -EINVAL); 1077 1078 /* Write starting at a valid location but going off the end */ 1079 spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1080 blob_op_complete, NULL); 1081 CU_ASSERT(g_bserrno == -EINVAL); 1082 1083 spdk_blob_close(blob, blob_op_complete, NULL); 1084 CU_ASSERT(g_bserrno == 0); 1085 1086 spdk_bs_free_io_channel(channel); 1087 1088 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1089 CU_ASSERT(g_bserrno == 0); 1090 g_bs = NULL; 1091 } 1092 1093 static void 1094 blob_read(void) 1095 { 1096 struct spdk_blob_store *bs; 1097 struct spdk_bs_dev *dev; 1098 struct spdk_blob *blob; 1099 struct spdk_io_channel *channel; 1100 spdk_blob_id blobid; 1101 uint64_t pages_per_cluster; 1102 uint8_t payload[10 * 4096]; 1103 1104 dev = init_dev(); 1105 1106 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1107 CU_ASSERT(g_bserrno == 0); 1108 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1109 bs = g_bs; 1110 1111 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1112 1113 channel = spdk_bs_alloc_io_channel(bs); 1114 CU_ASSERT(channel != NULL); 1115 1116 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1117 CU_ASSERT(g_bserrno == 0); 1118 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1119 blobid = g_blobid; 1120 1121 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1122 CU_ASSERT(g_bserrno == 0); 1123 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1124 blob = g_blob; 1125 1126 /* Read from a blob with 0 size */ 1127 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1128 CU_ASSERT(g_bserrno == -EINVAL); 1129 1130 /* Resize the blob */ 1131 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1132 CU_ASSERT(g_bserrno == 0); 1133 1134 /* Confirm that read passes if blob is marked read-only. */ 1135 blob->data_ro = true; 1136 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1137 CU_ASSERT(g_bserrno == 0); 1138 blob->data_ro = false; 1139 1140 /* Read from the blob */ 1141 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1142 CU_ASSERT(g_bserrno == 0); 1143 1144 /* Read starting beyond the end */ 1145 spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1146 NULL); 1147 CU_ASSERT(g_bserrno == -EINVAL); 1148 1149 /* Read starting at a valid location but going off the end */ 1150 spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1151 blob_op_complete, NULL); 1152 CU_ASSERT(g_bserrno == -EINVAL); 1153 1154 spdk_blob_close(blob, blob_op_complete, NULL); 1155 CU_ASSERT(g_bserrno == 0); 1156 1157 spdk_bs_free_io_channel(channel); 1158 1159 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1160 CU_ASSERT(g_bserrno == 0); 1161 g_bs = NULL; 1162 } 1163 1164 static void 1165 blob_rw_verify(void) 1166 { 1167 struct spdk_blob_store *bs; 1168 struct spdk_bs_dev *dev; 1169 struct spdk_blob *blob; 1170 struct spdk_io_channel *channel; 1171 spdk_blob_id blobid; 1172 uint8_t payload_read[10 * 4096]; 1173 uint8_t payload_write[10 * 4096]; 1174 1175 dev = init_dev(); 1176 1177 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1178 CU_ASSERT(g_bserrno == 0); 1179 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1180 bs = g_bs; 1181 1182 channel = spdk_bs_alloc_io_channel(bs); 1183 CU_ASSERT(channel != NULL); 1184 1185 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1186 CU_ASSERT(g_bserrno == 0); 1187 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1188 blobid = g_blobid; 1189 1190 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1191 CU_ASSERT(g_bserrno == 0); 1192 CU_ASSERT(g_blob != NULL); 1193 blob = g_blob; 1194 1195 spdk_blob_resize(blob, 32, blob_op_complete, NULL); 1196 CU_ASSERT(g_bserrno == 0); 1197 1198 memset(payload_write, 0xE5, sizeof(payload_write)); 1199 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 1200 CU_ASSERT(g_bserrno == 0); 1201 1202 memset(payload_read, 0x00, sizeof(payload_read)); 1203 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 1204 CU_ASSERT(g_bserrno == 0); 1205 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 1206 1207 spdk_blob_close(blob, blob_op_complete, NULL); 1208 CU_ASSERT(g_bserrno == 0); 1209 1210 spdk_bs_free_io_channel(channel); 1211 1212 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1213 CU_ASSERT(g_bserrno == 0); 1214 g_bs = NULL; 1215 } 1216 1217 static void 1218 blob_rw_verify_iov(void) 1219 { 1220 struct spdk_blob_store *bs; 1221 struct spdk_bs_dev *dev; 1222 struct spdk_blob *blob; 1223 struct spdk_io_channel *channel; 1224 spdk_blob_id blobid; 1225 uint8_t payload_read[10 * 4096]; 1226 uint8_t payload_write[10 * 4096]; 1227 struct iovec iov_read[3]; 1228 struct iovec iov_write[3]; 1229 void *buf; 1230 1231 dev = init_dev(); 1232 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1233 1234 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1235 CU_ASSERT(g_bserrno == 0); 1236 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1237 bs = g_bs; 1238 1239 channel = spdk_bs_alloc_io_channel(bs); 1240 CU_ASSERT(channel != NULL); 1241 1242 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1243 CU_ASSERT(g_bserrno == 0); 1244 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1245 blobid = g_blobid; 1246 1247 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1248 CU_ASSERT(g_bserrno == 0); 1249 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1250 blob = g_blob; 1251 1252 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1253 CU_ASSERT(g_bserrno == 0); 1254 1255 /* 1256 * Manually adjust the offset of the blob's second cluster. This allows 1257 * us to make sure that the readv/write code correctly accounts for I/O 1258 * that cross cluster boundaries. Start by asserting that the allocated 1259 * clusters are where we expect before modifying the second cluster. 1260 */ 1261 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 1262 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 1263 blob->active.clusters[1] = 3 * 256; 1264 1265 memset(payload_write, 0xE5, sizeof(payload_write)); 1266 iov_write[0].iov_base = payload_write; 1267 iov_write[0].iov_len = 1 * 4096; 1268 iov_write[1].iov_base = payload_write + 1 * 4096; 1269 iov_write[1].iov_len = 5 * 4096; 1270 iov_write[2].iov_base = payload_write + 6 * 4096; 1271 iov_write[2].iov_len = 4 * 4096; 1272 /* 1273 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1274 * will get written to the first cluster, the last 4 to the second cluster. 1275 */ 1276 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1277 CU_ASSERT(g_bserrno == 0); 1278 1279 memset(payload_read, 0xAA, sizeof(payload_read)); 1280 iov_read[0].iov_base = payload_read; 1281 iov_read[0].iov_len = 3 * 4096; 1282 iov_read[1].iov_base = payload_read + 3 * 4096; 1283 iov_read[1].iov_len = 4 * 4096; 1284 iov_read[2].iov_base = payload_read + 7 * 4096; 1285 iov_read[2].iov_len = 3 * 4096; 1286 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 1287 CU_ASSERT(g_bserrno == 0); 1288 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 1289 1290 buf = calloc(1, 256 * 4096); 1291 SPDK_CU_ASSERT_FATAL(buf != NULL); 1292 /* Check that cluster 2 on "disk" was not modified. */ 1293 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 1294 free(buf); 1295 1296 spdk_blob_close(blob, blob_op_complete, NULL); 1297 CU_ASSERT(g_bserrno == 0); 1298 1299 spdk_bs_free_io_channel(channel); 1300 1301 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1302 CU_ASSERT(g_bserrno == 0); 1303 g_bs = NULL; 1304 } 1305 1306 static uint32_t 1307 bs_channel_get_req_count(struct spdk_io_channel *_channel) 1308 { 1309 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 1310 struct spdk_bs_request_set *set; 1311 uint32_t count = 0; 1312 1313 TAILQ_FOREACH(set, &channel->reqs, link) { 1314 count++; 1315 } 1316 1317 return count; 1318 } 1319 1320 static void 1321 blob_rw_verify_iov_nomem(void) 1322 { 1323 struct spdk_blob_store *bs; 1324 struct spdk_bs_dev *dev; 1325 struct spdk_blob *blob; 1326 struct spdk_io_channel *channel; 1327 spdk_blob_id blobid; 1328 uint8_t payload_write[10 * 4096]; 1329 struct iovec iov_write[3]; 1330 uint32_t req_count; 1331 1332 dev = init_dev(); 1333 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1334 1335 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1336 CU_ASSERT(g_bserrno == 0); 1337 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1338 bs = g_bs; 1339 1340 channel = spdk_bs_alloc_io_channel(bs); 1341 CU_ASSERT(channel != NULL); 1342 1343 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1344 CU_ASSERT(g_bserrno == 0); 1345 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1346 blobid = g_blobid; 1347 1348 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1349 CU_ASSERT(g_bserrno == 0); 1350 CU_ASSERT(g_blob != NULL); 1351 blob = g_blob; 1352 1353 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1354 CU_ASSERT(g_bserrno == 0); 1355 1356 /* 1357 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1358 * will get written to the first cluster, the last 4 to the second cluster. 1359 */ 1360 iov_write[0].iov_base = payload_write; 1361 iov_write[0].iov_len = 1 * 4096; 1362 iov_write[1].iov_base = payload_write + 1 * 4096; 1363 iov_write[1].iov_len = 5 * 4096; 1364 iov_write[2].iov_base = payload_write + 6 * 4096; 1365 iov_write[2].iov_len = 4 * 4096; 1366 MOCK_SET(calloc, void *, NULL); 1367 req_count = bs_channel_get_req_count(channel); 1368 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1369 CU_ASSERT(g_bserrno = -ENOMEM); 1370 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 1371 MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU); 1372 1373 spdk_blob_close(blob, blob_op_complete, NULL); 1374 CU_ASSERT(g_bserrno == 0); 1375 1376 spdk_bs_free_io_channel(channel); 1377 1378 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1379 CU_ASSERT(g_bserrno == 0); 1380 g_bs = NULL; 1381 } 1382 1383 static void 1384 blob_rw_iov_read_only(void) 1385 { 1386 struct spdk_blob_store *bs; 1387 struct spdk_bs_dev *dev; 1388 struct spdk_blob *blob; 1389 struct spdk_io_channel *channel; 1390 spdk_blob_id blobid; 1391 uint8_t payload_read[4096]; 1392 uint8_t payload_write[4096]; 1393 struct iovec iov_read; 1394 struct iovec iov_write; 1395 1396 dev = init_dev(); 1397 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1398 1399 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1400 CU_ASSERT(g_bserrno == 0); 1401 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1402 bs = g_bs; 1403 1404 channel = spdk_bs_alloc_io_channel(bs); 1405 CU_ASSERT(channel != NULL); 1406 1407 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1408 CU_ASSERT(g_bserrno == 0); 1409 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1410 blobid = g_blobid; 1411 1412 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1413 CU_ASSERT(g_bserrno == 0); 1414 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1415 blob = g_blob; 1416 1417 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1418 CU_ASSERT(g_bserrno == 0); 1419 1420 /* Verify that writev failed if read_only flag is set. */ 1421 blob->data_ro = true; 1422 iov_write.iov_base = payload_write; 1423 iov_write.iov_len = sizeof(payload_write); 1424 spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL); 1425 CU_ASSERT(g_bserrno == -EPERM); 1426 1427 /* Verify that reads pass if data_ro flag is set. */ 1428 iov_read.iov_base = payload_read; 1429 iov_read.iov_len = sizeof(payload_read); 1430 spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL); 1431 CU_ASSERT(g_bserrno == 0); 1432 1433 spdk_blob_close(blob, blob_op_complete, NULL); 1434 CU_ASSERT(g_bserrno == 0); 1435 1436 spdk_bs_free_io_channel(channel); 1437 1438 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1439 CU_ASSERT(g_bserrno == 0); 1440 g_bs = NULL; 1441 } 1442 1443 static void 1444 blob_unmap(void) 1445 { 1446 struct spdk_blob_store *bs; 1447 struct spdk_bs_dev *dev; 1448 struct spdk_blob *blob; 1449 struct spdk_io_channel *channel; 1450 spdk_blob_id blobid; 1451 struct spdk_blob_opts opts; 1452 uint8_t payload[4096]; 1453 int i; 1454 1455 dev = init_dev(); 1456 1457 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1458 CU_ASSERT(g_bserrno == 0); 1459 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1460 bs = g_bs; 1461 1462 channel = spdk_bs_alloc_io_channel(bs); 1463 CU_ASSERT(channel != NULL); 1464 1465 spdk_blob_opts_init(&opts); 1466 opts.num_clusters = 10; 1467 1468 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1469 CU_ASSERT(g_bserrno == 0); 1470 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1471 blobid = g_blobid; 1472 1473 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1474 CU_ASSERT(g_bserrno == 0); 1475 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1476 blob = g_blob; 1477 1478 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 1479 CU_ASSERT(g_bserrno == 0); 1480 1481 memset(payload, 0, sizeof(payload)); 1482 payload[0] = 0xFF; 1483 1484 /* 1485 * Set first byte of every cluster to 0xFF. 1486 * First cluster on device is reserved so let's start from cluster number 1 1487 */ 1488 for (i = 1; i < 11; i++) { 1489 g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF; 1490 } 1491 1492 /* Confirm writes */ 1493 for (i = 0; i < 10; i++) { 1494 payload[0] = 0; 1495 spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1, 1496 blob_op_complete, NULL); 1497 CU_ASSERT(g_bserrno == 0); 1498 CU_ASSERT(payload[0] == 0xFF); 1499 } 1500 1501 /* Mark some clusters as unallocated */ 1502 blob->active.clusters[1] = 0; 1503 blob->active.clusters[2] = 0; 1504 blob->active.clusters[3] = 0; 1505 blob->active.clusters[6] = 0; 1506 blob->active.clusters[8] = 0; 1507 1508 /* Unmap clusters by resizing to 0 */ 1509 spdk_blob_resize(blob, 0, blob_op_complete, NULL); 1510 CU_ASSERT(g_bserrno == 0); 1511 1512 spdk_blob_sync_md(blob, blob_op_complete, NULL); 1513 CU_ASSERT(g_bserrno == 0); 1514 1515 /* Confirm that only 'allocated' clusters were unmaped */ 1516 for (i = 1; i < 11; i++) { 1517 switch (i) { 1518 case 2: 1519 case 3: 1520 case 4: 1521 case 7: 1522 case 9: 1523 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF); 1524 break; 1525 default: 1526 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0); 1527 break; 1528 } 1529 } 1530 1531 spdk_blob_close(blob, blob_op_complete, NULL); 1532 CU_ASSERT(g_bserrno == 0); 1533 1534 spdk_bs_free_io_channel(channel); 1535 1536 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1537 CU_ASSERT(g_bserrno == 0); 1538 g_bs = NULL; 1539 } 1540 1541 1542 static void 1543 blob_iter(void) 1544 { 1545 struct spdk_blob_store *bs; 1546 struct spdk_bs_dev *dev; 1547 struct spdk_blob *blob; 1548 spdk_blob_id blobid; 1549 1550 dev = init_dev(); 1551 1552 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1553 CU_ASSERT(g_bserrno == 0); 1554 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1555 bs = g_bs; 1556 1557 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1558 CU_ASSERT(g_blob == NULL); 1559 CU_ASSERT(g_bserrno == -ENOENT); 1560 1561 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1562 CU_ASSERT(g_bserrno == 0); 1563 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1564 blobid = g_blobid; 1565 1566 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1567 CU_ASSERT(g_blob != NULL); 1568 CU_ASSERT(g_bserrno == 0); 1569 blob = g_blob; 1570 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 1571 1572 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 1573 CU_ASSERT(g_blob == NULL); 1574 CU_ASSERT(g_bserrno == -ENOENT); 1575 1576 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1577 CU_ASSERT(g_bserrno == 0); 1578 g_bs = NULL; 1579 } 1580 1581 static void 1582 blob_xattr(void) 1583 { 1584 struct spdk_blob_store *bs; 1585 struct spdk_bs_dev *dev; 1586 struct spdk_blob *blob; 1587 spdk_blob_id blobid; 1588 uint64_t length; 1589 int rc; 1590 const char *name1, *name2; 1591 const void *value; 1592 size_t value_len; 1593 struct spdk_xattr_names *names; 1594 1595 dev = init_dev(); 1596 1597 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1598 CU_ASSERT(g_bserrno == 0); 1599 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1600 bs = g_bs; 1601 1602 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1603 CU_ASSERT(g_bserrno == 0); 1604 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1605 blobid = g_blobid; 1606 1607 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1608 CU_ASSERT(g_bserrno == 0); 1609 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1610 blob = g_blob; 1611 1612 /* Test that set_xattr fails if md_ro flag is set. */ 1613 blob->md_ro = true; 1614 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1615 CU_ASSERT(rc == -EPERM); 1616 1617 blob->md_ro = false; 1618 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1619 CU_ASSERT(rc == 0); 1620 1621 length = 2345; 1622 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1623 CU_ASSERT(rc == 0); 1624 1625 /* Overwrite "length" xattr. */ 1626 length = 3456; 1627 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1628 CU_ASSERT(rc == 0); 1629 1630 /* get_xattr should still work even if md_ro flag is set. */ 1631 value = NULL; 1632 blob->md_ro = true; 1633 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1634 CU_ASSERT(rc == 0); 1635 SPDK_CU_ASSERT_FATAL(value != NULL); 1636 CU_ASSERT(*(uint64_t *)value == length); 1637 CU_ASSERT(value_len == 8); 1638 blob->md_ro = false; 1639 1640 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1641 CU_ASSERT(rc == -ENOENT); 1642 1643 names = NULL; 1644 rc = spdk_blob_get_xattr_names(blob, &names); 1645 CU_ASSERT(rc == 0); 1646 SPDK_CU_ASSERT_FATAL(names != NULL); 1647 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 1648 name1 = spdk_xattr_names_get_name(names, 0); 1649 SPDK_CU_ASSERT_FATAL(name1 != NULL); 1650 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 1651 name2 = spdk_xattr_names_get_name(names, 1); 1652 SPDK_CU_ASSERT_FATAL(name2 != NULL); 1653 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 1654 CU_ASSERT(strcmp(name1, name2)); 1655 spdk_xattr_names_free(names); 1656 1657 /* Confirm that remove_xattr fails if md_ro is set to true. */ 1658 blob->md_ro = true; 1659 rc = spdk_blob_remove_xattr(blob, "name"); 1660 CU_ASSERT(rc == -EPERM); 1661 1662 blob->md_ro = false; 1663 rc = spdk_blob_remove_xattr(blob, "name"); 1664 CU_ASSERT(rc == 0); 1665 1666 rc = spdk_blob_remove_xattr(blob, "foobar"); 1667 CU_ASSERT(rc == -ENOENT); 1668 1669 /* Set internal xattr */ 1670 length = 7898; 1671 rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true); 1672 CU_ASSERT(rc == 0); 1673 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 1674 CU_ASSERT(rc == 0); 1675 CU_ASSERT(*(uint64_t *)value == length); 1676 /* try to get public xattr with same name */ 1677 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 1678 CU_ASSERT(rc != 0); 1679 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false); 1680 CU_ASSERT(rc != 0); 1681 /* Check if SPDK_BLOB_INTERNAL_XATTR is set */ 1682 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 1683 SPDK_BLOB_INTERNAL_XATTR) 1684 1685 spdk_blob_close(blob, blob_op_complete, NULL); 1686 1687 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1688 1689 /* Check if xattrs are persisted */ 1690 dev = init_dev(); 1691 1692 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 1693 CU_ASSERT(g_bserrno == 0); 1694 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1695 1696 bs = g_bs; 1697 1698 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1699 CU_ASSERT(g_bserrno == 0); 1700 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1701 blob = g_blob; 1702 1703 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 1704 CU_ASSERT(rc == 0); 1705 CU_ASSERT(*(uint64_t *)value == length); 1706 1707 /* try to get internal xattr trough public call */ 1708 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 1709 CU_ASSERT(rc != 0); 1710 1711 rc = _spdk_blob_remove_xattr(blob, "internal", true); 1712 CU_ASSERT(rc == 0); 1713 1714 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0); 1715 1716 CU_ASSERT(g_bserrno == 0); 1717 g_bs = NULL; 1718 } 1719 1720 static void 1721 bs_load(void) 1722 { 1723 struct spdk_bs_dev *dev; 1724 spdk_blob_id blobid; 1725 struct spdk_blob *blob; 1726 struct spdk_bs_super_block *super_block; 1727 uint64_t length; 1728 int rc; 1729 const void *value; 1730 size_t value_len; 1731 struct spdk_bs_opts opts; 1732 1733 dev = init_dev(); 1734 spdk_bs_opts_init(&opts); 1735 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1736 1737 /* Initialize a new blob store */ 1738 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1739 CU_ASSERT(g_bserrno == 0); 1740 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1741 1742 /* Try to open a blobid that does not exist */ 1743 spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 1744 CU_ASSERT(g_bserrno == -ENOENT); 1745 CU_ASSERT(g_blob == NULL); 1746 1747 /* Create a blob */ 1748 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1749 CU_ASSERT(g_bserrno == 0); 1750 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1751 blobid = g_blobid; 1752 1753 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1754 CU_ASSERT(g_bserrno == 0); 1755 CU_ASSERT(g_blob != NULL); 1756 blob = g_blob; 1757 1758 /* Try again to open valid blob but without the upper bit set */ 1759 spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 1760 CU_ASSERT(g_bserrno == -ENOENT); 1761 CU_ASSERT(g_blob == NULL); 1762 1763 /* Set some xattrs */ 1764 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1765 CU_ASSERT(rc == 0); 1766 1767 length = 2345; 1768 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1769 CU_ASSERT(rc == 0); 1770 1771 /* Resize the blob */ 1772 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 1773 CU_ASSERT(g_bserrno == 0); 1774 1775 spdk_blob_close(blob, blob_op_complete, NULL); 1776 CU_ASSERT(g_bserrno == 0); 1777 blob = NULL; 1778 g_blob = NULL; 1779 g_blobid = SPDK_BLOBID_INVALID; 1780 1781 /* Unload the blob store */ 1782 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1783 CU_ASSERT(g_bserrno == 0); 1784 g_bs = NULL; 1785 g_blob = NULL; 1786 g_blobid = 0; 1787 1788 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1789 CU_ASSERT(super_block->clean == 1); 1790 1791 /* Load should fail for device with an unsupported blocklen */ 1792 dev = init_dev(); 1793 dev->blocklen = SPDK_BS_PAGE_SIZE * 2; 1794 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 1795 CU_ASSERT(g_bserrno == -EINVAL); 1796 1797 /* Load should when max_md_ops is set to zero */ 1798 dev = init_dev(); 1799 spdk_bs_opts_init(&opts); 1800 opts.max_md_ops = 0; 1801 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1802 CU_ASSERT(g_bserrno == -EINVAL); 1803 1804 /* Load should when max_channel_ops is set to zero */ 1805 dev = init_dev(); 1806 spdk_bs_opts_init(&opts); 1807 opts.max_channel_ops = 0; 1808 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1809 CU_ASSERT(g_bserrno == -EINVAL); 1810 1811 /* Load an existing blob store */ 1812 dev = init_dev(); 1813 spdk_bs_opts_init(&opts); 1814 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1815 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1816 CU_ASSERT(g_bserrno == 0); 1817 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1818 1819 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1820 CU_ASSERT(super_block->clean == 0); 1821 1822 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1823 CU_ASSERT(g_bserrno == 0); 1824 CU_ASSERT(g_blob != NULL); 1825 blob = g_blob; 1826 1827 /* Get the xattrs */ 1828 value = NULL; 1829 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1830 CU_ASSERT(rc == 0); 1831 SPDK_CU_ASSERT_FATAL(value != NULL); 1832 CU_ASSERT(*(uint64_t *)value == length); 1833 CU_ASSERT(value_len == 8); 1834 1835 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1836 CU_ASSERT(rc == -ENOENT); 1837 1838 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1839 1840 spdk_blob_close(blob, blob_op_complete, NULL); 1841 CU_ASSERT(g_bserrno == 0); 1842 blob = NULL; 1843 g_blob = NULL; 1844 g_blobid = SPDK_BLOBID_INVALID; 1845 1846 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1847 CU_ASSERT(g_bserrno == 0); 1848 g_bs = NULL; 1849 } 1850 1851 static void 1852 bs_type(void) 1853 { 1854 struct spdk_bs_dev *dev; 1855 struct spdk_bs_opts opts; 1856 1857 dev = init_dev(); 1858 spdk_bs_opts_init(&opts); 1859 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1860 1861 /* Initialize a new blob store */ 1862 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1863 CU_ASSERT(g_bserrno == 0); 1864 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1865 1866 /* Unload the blob store */ 1867 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1868 CU_ASSERT(g_bserrno == 0); 1869 g_bs = NULL; 1870 g_blob = NULL; 1871 g_blobid = 0; 1872 1873 /* Load non existing blobstore type */ 1874 dev = init_dev(); 1875 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 1876 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1877 CU_ASSERT(g_bserrno != 0); 1878 1879 /* Load with empty blobstore type */ 1880 dev = init_dev(); 1881 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1882 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1883 CU_ASSERT(g_bserrno == 0); 1884 1885 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1886 CU_ASSERT(g_bserrno == 0); 1887 g_bs = NULL; 1888 1889 /* Initialize a new blob store with empty bstype */ 1890 dev = init_dev(); 1891 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1892 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1893 CU_ASSERT(g_bserrno == 0); 1894 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1895 1896 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1897 CU_ASSERT(g_bserrno == 0); 1898 g_bs = NULL; 1899 1900 /* Load non existing blobstore type */ 1901 dev = init_dev(); 1902 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 1903 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1904 CU_ASSERT(g_bserrno != 0); 1905 1906 /* Load with empty blobstore type */ 1907 dev = init_dev(); 1908 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1909 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1910 CU_ASSERT(g_bserrno == 0); 1911 1912 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1913 CU_ASSERT(g_bserrno == 0); 1914 g_bs = NULL; 1915 } 1916 1917 static void 1918 bs_super_block(void) 1919 { 1920 struct spdk_bs_dev *dev; 1921 struct spdk_bs_super_block *super_block; 1922 struct spdk_bs_opts opts; 1923 struct spdk_bs_super_block_ver1 super_block_v1; 1924 1925 dev = init_dev(); 1926 spdk_bs_opts_init(&opts); 1927 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1928 1929 /* Initialize a new blob store */ 1930 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1931 CU_ASSERT(g_bserrno == 0); 1932 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1933 1934 /* Unload the blob store */ 1935 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1936 CU_ASSERT(g_bserrno == 0); 1937 g_bs = NULL; 1938 g_blob = NULL; 1939 g_blobid = 0; 1940 1941 /* Load an existing blob store with version newer than supported */ 1942 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1943 super_block->version++; 1944 1945 dev = init_dev(); 1946 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1947 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1948 CU_ASSERT(g_bserrno != 0); 1949 1950 /* Create a new blob store with super block version 1 */ 1951 dev = init_dev(); 1952 super_block_v1.version = 1; 1953 memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 1954 super_block_v1.length = 0x1000; 1955 super_block_v1.clean = 1; 1956 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 1957 super_block_v1.cluster_size = 0x100000; 1958 super_block_v1.used_page_mask_start = 0x01; 1959 super_block_v1.used_page_mask_len = 0x01; 1960 super_block_v1.used_cluster_mask_start = 0x02; 1961 super_block_v1.used_cluster_mask_len = 0x01; 1962 super_block_v1.md_start = 0x03; 1963 super_block_v1.md_len = 0x40; 1964 memset(super_block_v1.reserved, 0, 4036); 1965 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 1966 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 1967 1968 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1969 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1970 CU_ASSERT(g_bserrno == 0); 1971 1972 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1973 CU_ASSERT(g_bserrno == 0); 1974 g_bs = NULL; 1975 } 1976 1977 /* 1978 * Create a blobstore and then unload it. 1979 */ 1980 static void 1981 bs_unload(void) 1982 { 1983 struct spdk_bs_dev *dev; 1984 struct spdk_blob_store *bs; 1985 spdk_blob_id blobid; 1986 struct spdk_blob *blob; 1987 1988 dev = init_dev(); 1989 1990 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1991 CU_ASSERT(g_bserrno == 0); 1992 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1993 bs = g_bs; 1994 1995 /* Create a blob and open it. */ 1996 g_bserrno = -1; 1997 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1998 CU_ASSERT(g_bserrno == 0); 1999 CU_ASSERT(g_blobid > 0); 2000 blobid = g_blobid; 2001 2002 g_bserrno = -1; 2003 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2004 CU_ASSERT(g_bserrno == 0); 2005 CU_ASSERT(g_blob != NULL); 2006 blob = g_blob; 2007 2008 /* Try to unload blobstore, should fail with open blob */ 2009 g_bserrno = -1; 2010 spdk_bs_unload(bs, bs_op_complete, NULL); 2011 CU_ASSERT(g_bserrno == -EBUSY); 2012 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2013 2014 /* Close the blob, then successfully unload blobstore */ 2015 g_bserrno = -1; 2016 spdk_blob_close(blob, blob_op_complete, NULL); 2017 CU_ASSERT(g_bserrno == 0); 2018 2019 g_bserrno = -1; 2020 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2021 CU_ASSERT(g_bserrno == 0); 2022 g_bs = NULL; 2023 } 2024 2025 /* 2026 * Create a blobstore with a cluster size different than the default, and ensure it is 2027 * persisted. 2028 */ 2029 static void 2030 bs_cluster_sz(void) 2031 { 2032 struct spdk_bs_dev *dev; 2033 struct spdk_bs_opts opts; 2034 uint32_t cluster_sz; 2035 2036 /* Set cluster size to zero */ 2037 dev = init_dev(); 2038 spdk_bs_opts_init(&opts); 2039 opts.cluster_sz = 0; 2040 2041 /* Initialize a new blob store */ 2042 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2043 CU_ASSERT(g_bserrno == -EINVAL); 2044 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2045 2046 /* 2047 * Set cluster size to blobstore page size, 2048 * to work it is required to be at least twice the blobstore page size. 2049 */ 2050 dev = init_dev(); 2051 spdk_bs_opts_init(&opts); 2052 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 2053 2054 /* Initialize a new blob store */ 2055 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2056 CU_ASSERT(g_bserrno == -ENOMEM); 2057 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2058 2059 /* 2060 * Set cluster size to lower than page size, 2061 * to work it is required to be at least twice the blobstore page size. 2062 */ 2063 dev = init_dev(); 2064 spdk_bs_opts_init(&opts); 2065 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 2066 2067 /* Initialize a new blob store */ 2068 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2069 CU_ASSERT(g_bserrno == -ENOMEM); 2070 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2071 2072 /* Set cluster size to twice the default */ 2073 dev = init_dev(); 2074 spdk_bs_opts_init(&opts); 2075 opts.cluster_sz *= 2; 2076 cluster_sz = opts.cluster_sz; 2077 2078 /* Initialize a new blob store */ 2079 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2080 CU_ASSERT(g_bserrno == 0); 2081 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2082 2083 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2084 2085 /* Unload the blob store */ 2086 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2087 CU_ASSERT(g_bserrno == 0); 2088 g_bs = NULL; 2089 g_blob = NULL; 2090 g_blobid = 0; 2091 2092 dev = init_dev(); 2093 /* Load an existing blob store */ 2094 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2095 CU_ASSERT(g_bserrno == 0); 2096 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2097 2098 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2099 2100 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2101 CU_ASSERT(g_bserrno == 0); 2102 g_bs = NULL; 2103 } 2104 2105 /* 2106 * Create a blobstore, reload it and ensure total usable cluster count 2107 * stays the same. 2108 */ 2109 static void 2110 bs_usable_clusters(void) 2111 { 2112 struct spdk_bs_dev *dev; 2113 struct spdk_bs_opts opts; 2114 uint32_t clusters; 2115 int i; 2116 2117 /* Init blobstore */ 2118 dev = init_dev(); 2119 spdk_bs_opts_init(&opts); 2120 2121 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2122 CU_ASSERT(g_bserrno == 0); 2123 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2124 2125 clusters = spdk_bs_total_data_cluster_count(g_bs); 2126 2127 /* Unload the blob store */ 2128 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2129 CU_ASSERT(g_bserrno == 0); 2130 g_bs = NULL; 2131 2132 dev = init_dev(); 2133 /* Load an existing blob store */ 2134 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2135 CU_ASSERT(g_bserrno == 0); 2136 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2137 2138 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2139 2140 /* Create and resize blobs to make sure that useable cluster count won't change */ 2141 for (i = 0; i < 4; i++) { 2142 g_bserrno = -1; 2143 g_blobid = SPDK_BLOBID_INVALID; 2144 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2145 CU_ASSERT(g_bserrno == 0); 2146 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2147 2148 g_bserrno = -1; 2149 g_blob = NULL; 2150 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 2151 CU_ASSERT(g_bserrno == 0); 2152 CU_ASSERT(g_blob != NULL); 2153 2154 spdk_blob_resize(g_blob, 10, blob_op_complete, NULL); 2155 CU_ASSERT(g_bserrno == 0); 2156 2157 g_bserrno = -1; 2158 spdk_blob_close(g_blob, blob_op_complete, NULL); 2159 CU_ASSERT(g_bserrno == 0); 2160 2161 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2162 } 2163 2164 /* Reload the blob store to make sure that nothing changed */ 2165 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2166 CU_ASSERT(g_bserrno == 0); 2167 g_bs = NULL; 2168 2169 dev = init_dev(); 2170 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2171 CU_ASSERT(g_bserrno == 0); 2172 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2173 2174 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2175 2176 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2177 CU_ASSERT(g_bserrno == 0); 2178 g_bs = NULL; 2179 } 2180 2181 /* 2182 * Test resizing of the metadata blob. This requires creating enough blobs 2183 * so that one cluster is not enough to fit the metadata for those blobs. 2184 * To induce this condition to happen more quickly, we reduce the cluster 2185 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 2186 */ 2187 static void 2188 bs_resize_md(void) 2189 { 2190 const int CLUSTER_PAGE_COUNT = 4; 2191 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 2192 struct spdk_bs_dev *dev; 2193 struct spdk_bs_opts opts; 2194 uint32_t cluster_sz; 2195 spdk_blob_id blobids[NUM_BLOBS]; 2196 int i; 2197 2198 2199 dev = init_dev(); 2200 spdk_bs_opts_init(&opts); 2201 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 2202 cluster_sz = opts.cluster_sz; 2203 2204 /* Initialize a new blob store */ 2205 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2206 CU_ASSERT(g_bserrno == 0); 2207 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2208 2209 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2210 2211 for (i = 0; i < NUM_BLOBS; i++) { 2212 g_bserrno = -1; 2213 g_blobid = SPDK_BLOBID_INVALID; 2214 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2215 CU_ASSERT(g_bserrno == 0); 2216 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2217 blobids[i] = g_blobid; 2218 } 2219 2220 /* Unload the blob store */ 2221 g_bserrno = -1; 2222 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2223 CU_ASSERT(g_bserrno == 0); 2224 2225 /* Load an existing blob store */ 2226 g_bserrno = -1; 2227 g_bs = NULL; 2228 dev = init_dev(); 2229 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2230 CU_ASSERT(g_bserrno == 0); 2231 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2232 2233 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2234 2235 for (i = 0; i < NUM_BLOBS; i++) { 2236 g_bserrno = -1; 2237 g_blob = NULL; 2238 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 2239 CU_ASSERT(g_bserrno == 0); 2240 CU_ASSERT(g_blob != NULL); 2241 g_bserrno = -1; 2242 spdk_blob_close(g_blob, blob_op_complete, NULL); 2243 CU_ASSERT(g_bserrno == 0); 2244 } 2245 2246 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2247 CU_ASSERT(g_bserrno == 0); 2248 g_bs = NULL; 2249 } 2250 2251 static void 2252 bs_destroy(void) 2253 { 2254 struct spdk_bs_dev *dev; 2255 struct spdk_bs_opts opts; 2256 2257 /* Initialize a new blob store */ 2258 dev = init_dev(); 2259 spdk_bs_opts_init(&opts); 2260 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2261 CU_ASSERT(g_bserrno == 0); 2262 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2263 2264 /* Destroy the blob store */ 2265 g_bserrno = -1; 2266 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 2267 CU_ASSERT(g_bserrno == 0); 2268 2269 /* Loading an non-existent blob store should fail. */ 2270 g_bs = NULL; 2271 dev = init_dev(); 2272 2273 g_bserrno = 0; 2274 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2275 CU_ASSERT(g_bserrno != 0); 2276 } 2277 2278 /* Try to hit all of the corner cases associated with serializing 2279 * a blob to disk 2280 */ 2281 static void 2282 blob_serialize(void) 2283 { 2284 struct spdk_bs_dev *dev; 2285 struct spdk_bs_opts opts; 2286 struct spdk_blob_store *bs; 2287 spdk_blob_id blobid[2]; 2288 struct spdk_blob *blob[2]; 2289 uint64_t i; 2290 char *value; 2291 int rc; 2292 2293 dev = init_dev(); 2294 2295 /* Initialize a new blobstore with very small clusters */ 2296 spdk_bs_opts_init(&opts); 2297 opts.cluster_sz = dev->blocklen * 8; 2298 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2299 CU_ASSERT(g_bserrno == 0); 2300 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2301 bs = g_bs; 2302 2303 /* Create and open two blobs */ 2304 for (i = 0; i < 2; i++) { 2305 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2306 CU_ASSERT(g_bserrno == 0); 2307 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2308 blobid[i] = g_blobid; 2309 2310 /* Open a blob */ 2311 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2312 CU_ASSERT(g_bserrno == 0); 2313 CU_ASSERT(g_blob != NULL); 2314 blob[i] = g_blob; 2315 2316 /* Set a fairly large xattr on both blobs to eat up 2317 * metadata space 2318 */ 2319 value = calloc(dev->blocklen - 64, sizeof(char)); 2320 SPDK_CU_ASSERT_FATAL(value != NULL); 2321 memset(value, i, dev->blocklen / 2); 2322 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 2323 CU_ASSERT(rc == 0); 2324 free(value); 2325 } 2326 2327 /* Resize the blobs, alternating 1 cluster at a time. 2328 * This thwarts run length encoding and will cause spill 2329 * over of the extents. 2330 */ 2331 for (i = 0; i < 6; i++) { 2332 spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL); 2333 CU_ASSERT(g_bserrno == 0); 2334 } 2335 2336 for (i = 0; i < 2; i++) { 2337 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 2338 CU_ASSERT(g_bserrno == 0); 2339 } 2340 2341 /* Close the blobs */ 2342 for (i = 0; i < 2; i++) { 2343 spdk_blob_close(blob[i], blob_op_complete, NULL); 2344 CU_ASSERT(g_bserrno == 0); 2345 } 2346 2347 /* Unload the blobstore */ 2348 spdk_bs_unload(bs, bs_op_complete, NULL); 2349 CU_ASSERT(g_bserrno == 0); 2350 g_bs = NULL; 2351 g_blob = NULL; 2352 g_blobid = 0; 2353 bs = NULL; 2354 2355 dev = init_dev(); 2356 /* Load an existing blob store */ 2357 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2358 CU_ASSERT(g_bserrno == 0); 2359 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2360 bs = g_bs; 2361 2362 for (i = 0; i < 2; i++) { 2363 blob[i] = NULL; 2364 2365 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2366 CU_ASSERT(g_bserrno == 0); 2367 CU_ASSERT(g_blob != NULL); 2368 blob[i] = g_blob; 2369 2370 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 2371 2372 spdk_blob_close(blob[i], blob_op_complete, NULL); 2373 CU_ASSERT(g_bserrno == 0); 2374 } 2375 2376 spdk_bs_unload(bs, bs_op_complete, NULL); 2377 CU_ASSERT(g_bserrno == 0); 2378 g_bs = NULL; 2379 } 2380 2381 static void 2382 blob_crc(void) 2383 { 2384 struct spdk_blob_store *bs; 2385 struct spdk_bs_dev *dev; 2386 struct spdk_blob *blob; 2387 spdk_blob_id blobid; 2388 uint32_t page_num; 2389 int index; 2390 struct spdk_blob_md_page *page; 2391 2392 dev = init_dev(); 2393 2394 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2395 CU_ASSERT(g_bserrno == 0); 2396 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2397 bs = g_bs; 2398 2399 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2400 CU_ASSERT(g_bserrno == 0); 2401 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2402 blobid = g_blobid; 2403 2404 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2405 CU_ASSERT(g_bserrno == 0); 2406 CU_ASSERT(g_blob != NULL); 2407 blob = g_blob; 2408 2409 spdk_blob_close(blob, blob_op_complete, NULL); 2410 CU_ASSERT(g_bserrno == 0); 2411 2412 page_num = _spdk_bs_blobid_to_page(blobid); 2413 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 2414 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2415 page->crc = 0; 2416 2417 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2418 CU_ASSERT(g_bserrno == -EINVAL); 2419 CU_ASSERT(g_blob == NULL); 2420 g_bserrno = 0; 2421 2422 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2423 CU_ASSERT(g_bserrno == -EINVAL); 2424 2425 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2426 CU_ASSERT(g_bserrno == 0); 2427 g_bs = NULL; 2428 } 2429 2430 static void 2431 super_block_crc(void) 2432 { 2433 struct spdk_bs_dev *dev; 2434 struct spdk_bs_super_block *super_block; 2435 struct spdk_bs_opts opts; 2436 2437 dev = init_dev(); 2438 spdk_bs_opts_init(&opts); 2439 2440 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2441 CU_ASSERT(g_bserrno == 0); 2442 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2443 2444 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2445 CU_ASSERT(g_bserrno == 0); 2446 g_bs = NULL; 2447 2448 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2449 super_block->crc = 0; 2450 dev = init_dev(); 2451 2452 /* Load an existing blob store */ 2453 g_bserrno = 0; 2454 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2455 CU_ASSERT(g_bserrno == -EILSEQ); 2456 } 2457 2458 /* For blob dirty shutdown test case we do the following sub-test cases: 2459 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we 2460 * dirty shutdown and reload the blob store and verify the xattrs. 2461 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 2462 * reload the blob store and verify the clusters number. 2463 * 3 Create the second blob and then dirty shutdown, reload the blob store 2464 * and verify the second blob. 2465 * 4 Delete the second blob and then dirty shutdown, reload the blob store 2466 * and verify the second blob is invalid. 2467 * 5 Create the second blob again and also create the third blob, modify the 2468 * md of second blob which makes the md invalid, and then dirty shutdown, 2469 * reload the blob store verify the second blob, it should invalid and also 2470 * verify the third blob, it should correct. 2471 */ 2472 static void 2473 blob_dirty_shutdown(void) 2474 { 2475 int rc; 2476 int index; 2477 struct spdk_bs_dev *dev; 2478 spdk_blob_id blobid1, blobid2, blobid3; 2479 struct spdk_blob *blob; 2480 uint64_t length; 2481 uint64_t free_clusters; 2482 const void *value; 2483 size_t value_len; 2484 uint32_t page_num; 2485 struct spdk_blob_md_page *page; 2486 struct spdk_bs_opts opts; 2487 2488 dev = init_dev(); 2489 spdk_bs_opts_init(&opts); 2490 /* Initialize a new blob store */ 2491 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2492 CU_ASSERT(g_bserrno == 0); 2493 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2494 2495 /* Create first blob */ 2496 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2497 CU_ASSERT(g_bserrno == 0); 2498 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2499 blobid1 = g_blobid; 2500 2501 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2502 CU_ASSERT(g_bserrno == 0); 2503 CU_ASSERT(g_blob != NULL); 2504 blob = g_blob; 2505 2506 /* Set some xattrs */ 2507 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2508 CU_ASSERT(rc == 0); 2509 2510 length = 2345; 2511 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2512 CU_ASSERT(rc == 0); 2513 2514 /* Resize the blob */ 2515 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2516 CU_ASSERT(g_bserrno == 0); 2517 2518 /* Set the blob as the super blob */ 2519 spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL); 2520 CU_ASSERT(g_bserrno == 0); 2521 2522 free_clusters = spdk_bs_free_cluster_count(g_bs); 2523 2524 spdk_blob_close(blob, blob_op_complete, NULL); 2525 blob = NULL; 2526 g_blob = NULL; 2527 g_blobid = SPDK_BLOBID_INVALID; 2528 2529 /* Dirty shutdown */ 2530 _spdk_bs_free(g_bs); 2531 2532 /* reload blobstore */ 2533 dev = init_dev(); 2534 spdk_bs_opts_init(&opts); 2535 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2536 CU_ASSERT(g_bserrno == 0); 2537 2538 /* Get the super blob */ 2539 spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL); 2540 CU_ASSERT(g_bserrno == 0); 2541 CU_ASSERT(blobid1 == g_blobid); 2542 2543 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2544 CU_ASSERT(g_bserrno == 0); 2545 CU_ASSERT(g_blob != NULL); 2546 blob = g_blob; 2547 2548 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2549 2550 /* Get the xattrs */ 2551 value = NULL; 2552 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2553 CU_ASSERT(rc == 0); 2554 SPDK_CU_ASSERT_FATAL(value != NULL); 2555 CU_ASSERT(*(uint64_t *)value == length); 2556 CU_ASSERT(value_len == 8); 2557 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2558 2559 /* Resize the blob */ 2560 spdk_blob_resize(blob, 20, blob_op_complete, NULL); 2561 CU_ASSERT(g_bserrno == 0); 2562 2563 free_clusters = spdk_bs_free_cluster_count(g_bs); 2564 2565 spdk_blob_close(blob, blob_op_complete, NULL); 2566 CU_ASSERT(g_bserrno == 0); 2567 blob = NULL; 2568 g_blob = NULL; 2569 g_blobid = SPDK_BLOBID_INVALID; 2570 2571 /* Dirty shutdown */ 2572 _spdk_bs_free(g_bs); 2573 2574 /* reload the blobstore */ 2575 dev = init_dev(); 2576 spdk_bs_opts_init(&opts); 2577 /* Load an existing blob store */ 2578 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2579 CU_ASSERT(g_bserrno == 0); 2580 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2581 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2582 CU_ASSERT(g_bserrno == 0); 2583 CU_ASSERT(g_blob != NULL); 2584 blob = g_blob; 2585 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 2586 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2587 2588 spdk_blob_close(blob, blob_op_complete, NULL); 2589 CU_ASSERT(g_bserrno == 0); 2590 blob = NULL; 2591 g_blob = NULL; 2592 g_blobid = SPDK_BLOBID_INVALID; 2593 2594 /* Create second blob */ 2595 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2596 CU_ASSERT(g_bserrno == 0); 2597 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2598 blobid2 = g_blobid; 2599 2600 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2601 CU_ASSERT(g_bserrno == 0); 2602 CU_ASSERT(g_blob != NULL); 2603 blob = g_blob; 2604 2605 /* Set some xattrs */ 2606 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2607 CU_ASSERT(rc == 0); 2608 2609 length = 5432; 2610 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2611 CU_ASSERT(rc == 0); 2612 2613 /* Resize the blob */ 2614 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2615 CU_ASSERT(g_bserrno == 0); 2616 2617 free_clusters = spdk_bs_free_cluster_count(g_bs); 2618 2619 spdk_blob_close(blob, blob_op_complete, NULL); 2620 blob = NULL; 2621 g_blob = NULL; 2622 g_blobid = SPDK_BLOBID_INVALID; 2623 2624 /* Dirty shutdown */ 2625 _spdk_bs_free(g_bs); 2626 2627 /* reload the blobstore */ 2628 dev = init_dev(); 2629 spdk_bs_opts_init(&opts); 2630 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2631 CU_ASSERT(g_bserrno == 0); 2632 2633 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2634 CU_ASSERT(g_bserrno == 0); 2635 CU_ASSERT(g_blob != NULL); 2636 blob = g_blob; 2637 2638 /* Get the xattrs */ 2639 value = NULL; 2640 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2641 CU_ASSERT(rc == 0); 2642 SPDK_CU_ASSERT_FATAL(value != NULL); 2643 CU_ASSERT(*(uint64_t *)value == length); 2644 CU_ASSERT(value_len == 8); 2645 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2646 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2647 2648 spdk_blob_close(blob, blob_op_complete, NULL); 2649 CU_ASSERT(g_bserrno == 0); 2650 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 2651 CU_ASSERT(g_bserrno == 0); 2652 2653 free_clusters = spdk_bs_free_cluster_count(g_bs); 2654 2655 /* Dirty shutdown */ 2656 _spdk_bs_free(g_bs); 2657 /* reload the blobstore */ 2658 dev = init_dev(); 2659 spdk_bs_opts_init(&opts); 2660 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2661 CU_ASSERT(g_bserrno == 0); 2662 2663 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2664 CU_ASSERT(g_bserrno != 0); 2665 CU_ASSERT(g_blob == NULL); 2666 2667 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2668 CU_ASSERT(g_bserrno == 0); 2669 CU_ASSERT(g_blob != NULL); 2670 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2671 spdk_blob_close(g_blob, blob_op_complete, NULL); 2672 CU_ASSERT(g_bserrno == 0); 2673 2674 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2675 CU_ASSERT(g_bserrno == 0); 2676 g_bs = NULL; 2677 2678 /* reload the blobstore */ 2679 dev = init_dev(); 2680 spdk_bs_opts_init(&opts); 2681 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2682 CU_ASSERT(g_bserrno == 0); 2683 2684 /* Create second blob */ 2685 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2686 CU_ASSERT(g_bserrno == 0); 2687 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2688 blobid2 = g_blobid; 2689 2690 /* Create third blob */ 2691 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2692 CU_ASSERT(g_bserrno == 0); 2693 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2694 blobid3 = g_blobid; 2695 2696 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2697 CU_ASSERT(g_bserrno == 0); 2698 CU_ASSERT(g_blob != NULL); 2699 blob = g_blob; 2700 2701 /* Set some xattrs for second blob */ 2702 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2703 CU_ASSERT(rc == 0); 2704 2705 length = 5432; 2706 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2707 CU_ASSERT(rc == 0); 2708 2709 spdk_blob_close(blob, blob_op_complete, NULL); 2710 blob = NULL; 2711 g_blob = NULL; 2712 g_blobid = SPDK_BLOBID_INVALID; 2713 2714 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2715 CU_ASSERT(g_bserrno == 0); 2716 CU_ASSERT(g_blob != NULL); 2717 blob = g_blob; 2718 2719 /* Set some xattrs for third blob */ 2720 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 2721 CU_ASSERT(rc == 0); 2722 2723 length = 5432; 2724 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2725 CU_ASSERT(rc == 0); 2726 2727 spdk_blob_close(blob, blob_op_complete, NULL); 2728 blob = NULL; 2729 g_blob = NULL; 2730 g_blobid = SPDK_BLOBID_INVALID; 2731 2732 /* Mark second blob as invalid */ 2733 page_num = _spdk_bs_blobid_to_page(blobid2); 2734 2735 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 2736 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2737 page->sequence_num = 1; 2738 page->crc = _spdk_blob_md_page_calc_crc(page); 2739 2740 free_clusters = spdk_bs_free_cluster_count(g_bs); 2741 2742 /* Dirty shutdown */ 2743 _spdk_bs_free(g_bs); 2744 /* reload the blobstore */ 2745 dev = init_dev(); 2746 spdk_bs_opts_init(&opts); 2747 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2748 CU_ASSERT(g_bserrno == 0); 2749 2750 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2751 CU_ASSERT(g_bserrno != 0); 2752 CU_ASSERT(g_blob == NULL); 2753 2754 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2755 CU_ASSERT(g_bserrno == 0); 2756 CU_ASSERT(g_blob != NULL); 2757 blob = g_blob; 2758 2759 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2760 2761 spdk_blob_close(blob, blob_op_complete, NULL); 2762 blob = NULL; 2763 g_blob = NULL; 2764 g_blobid = SPDK_BLOBID_INVALID; 2765 2766 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2767 CU_ASSERT(g_bserrno == 0); 2768 g_bs = NULL; 2769 } 2770 2771 static void 2772 blob_flags(void) 2773 { 2774 struct spdk_bs_dev *dev; 2775 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 2776 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 2777 struct spdk_bs_opts opts; 2778 int rc; 2779 2780 dev = init_dev(); 2781 spdk_bs_opts_init(&opts); 2782 2783 /* Initialize a new blob store */ 2784 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2785 CU_ASSERT(g_bserrno == 0); 2786 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2787 2788 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 2789 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2790 CU_ASSERT(g_bserrno == 0); 2791 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2792 blobid_invalid = g_blobid; 2793 2794 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2795 CU_ASSERT(g_bserrno == 0); 2796 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2797 blobid_data_ro = g_blobid; 2798 2799 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2800 CU_ASSERT(g_bserrno == 0); 2801 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2802 blobid_md_ro = g_blobid; 2803 2804 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2805 CU_ASSERT(g_bserrno == 0); 2806 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2807 blob_invalid = g_blob; 2808 2809 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2810 CU_ASSERT(g_bserrno == 0); 2811 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2812 blob_data_ro = g_blob; 2813 2814 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2815 CU_ASSERT(g_bserrno == 0); 2816 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2817 blob_md_ro = g_blob; 2818 2819 /* Change the size of blob_data_ro to check if flags are serialized 2820 * when blob has non zero number of extents */ 2821 spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL); 2822 CU_ASSERT(g_bserrno == 0); 2823 2824 /* Set the xattr to check if flags are serialized 2825 * when blob has non zero number of xattrs */ 2826 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 2827 CU_ASSERT(rc == 0); 2828 2829 blob_invalid->invalid_flags = (1ULL << 63); 2830 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 2831 blob_data_ro->data_ro_flags = (1ULL << 62); 2832 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 2833 blob_md_ro->md_ro_flags = (1ULL << 61); 2834 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 2835 2836 g_bserrno = -1; 2837 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 2838 CU_ASSERT(g_bserrno == 0); 2839 g_bserrno = -1; 2840 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 2841 CU_ASSERT(g_bserrno == 0); 2842 g_bserrno = -1; 2843 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2844 CU_ASSERT(g_bserrno == 0); 2845 2846 g_bserrno = -1; 2847 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 2848 CU_ASSERT(g_bserrno == 0); 2849 blob_invalid = NULL; 2850 g_bserrno = -1; 2851 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2852 CU_ASSERT(g_bserrno == 0); 2853 blob_data_ro = NULL; 2854 g_bserrno = -1; 2855 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2856 CU_ASSERT(g_bserrno == 0); 2857 blob_md_ro = NULL; 2858 2859 g_blob = NULL; 2860 g_blobid = SPDK_BLOBID_INVALID; 2861 2862 /* Unload the blob store */ 2863 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2864 CU_ASSERT(g_bserrno == 0); 2865 g_bs = NULL; 2866 2867 /* Load an existing blob store */ 2868 dev = init_dev(); 2869 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2870 CU_ASSERT(g_bserrno == 0); 2871 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2872 2873 g_blob = NULL; 2874 g_bserrno = 0; 2875 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2876 CU_ASSERT(g_bserrno != 0); 2877 CU_ASSERT(g_blob == NULL); 2878 2879 g_blob = NULL; 2880 g_bserrno = -1; 2881 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2882 CU_ASSERT(g_bserrno == 0); 2883 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2884 blob_data_ro = g_blob; 2885 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 2886 CU_ASSERT(blob_data_ro->data_ro == true); 2887 CU_ASSERT(blob_data_ro->md_ro == true); 2888 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 2889 2890 g_blob = NULL; 2891 g_bserrno = -1; 2892 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2893 CU_ASSERT(g_bserrno == 0); 2894 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2895 blob_md_ro = g_blob; 2896 CU_ASSERT(blob_md_ro->data_ro == false); 2897 CU_ASSERT(blob_md_ro->md_ro == true); 2898 2899 g_bserrno = -1; 2900 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2901 CU_ASSERT(g_bserrno == 0); 2902 2903 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2904 CU_ASSERT(g_bserrno == 0); 2905 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2906 CU_ASSERT(g_bserrno == 0); 2907 2908 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2909 CU_ASSERT(g_bserrno == 0); 2910 } 2911 2912 static void 2913 bs_version(void) 2914 { 2915 struct spdk_bs_super_block *super; 2916 struct spdk_bs_dev *dev; 2917 struct spdk_bs_opts opts; 2918 spdk_blob_id blobid; 2919 2920 dev = init_dev(); 2921 spdk_bs_opts_init(&opts); 2922 2923 /* Initialize a new blob store */ 2924 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2925 CU_ASSERT(g_bserrno == 0); 2926 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2927 2928 /* Unload the blob store */ 2929 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2930 CU_ASSERT(g_bserrno == 0); 2931 g_bs = NULL; 2932 2933 /* 2934 * Change the bs version on disk. This will allow us to 2935 * test that the version does not get modified automatically 2936 * when loading and unloading the blobstore. 2937 */ 2938 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 2939 CU_ASSERT(super->version == SPDK_BS_VERSION); 2940 CU_ASSERT(super->clean == 1); 2941 super->version = 2; 2942 /* 2943 * Version 2 metadata does not have a used blobid mask, so clear 2944 * those fields in the super block and zero the corresponding 2945 * region on "disk". We will use this to ensure blob IDs are 2946 * correctly reconstructed. 2947 */ 2948 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 2949 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 2950 super->used_blobid_mask_start = 0; 2951 super->used_blobid_mask_len = 0; 2952 super->crc = _spdk_blob_md_page_calc_crc(super); 2953 2954 /* Load an existing blob store */ 2955 dev = init_dev(); 2956 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2957 CU_ASSERT(g_bserrno == 0); 2958 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2959 CU_ASSERT(super->clean == 0); 2960 2961 /* 2962 * Create a blob - just to make sure that when we unload it 2963 * results in writing the super block (since metadata pages 2964 * were allocated. 2965 */ 2966 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2967 CU_ASSERT(g_bserrno == 0); 2968 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2969 blobid = g_blobid; 2970 2971 /* Unload the blob store */ 2972 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2973 CU_ASSERT(g_bserrno == 0); 2974 g_bs = NULL; 2975 CU_ASSERT(super->version == 2); 2976 CU_ASSERT(super->used_blobid_mask_start == 0); 2977 CU_ASSERT(super->used_blobid_mask_len == 0); 2978 2979 dev = init_dev(); 2980 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2981 CU_ASSERT(g_bserrno == 0); 2982 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2983 2984 g_blob = NULL; 2985 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2986 CU_ASSERT(g_bserrno == 0); 2987 CU_ASSERT(g_blob != NULL); 2988 2989 spdk_blob_close(g_blob, blob_op_complete, NULL); 2990 CU_ASSERT(g_bserrno == 0); 2991 2992 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2993 CU_ASSERT(g_bserrno == 0); 2994 g_bs = NULL; 2995 CU_ASSERT(super->version == 2); 2996 CU_ASSERT(super->used_blobid_mask_start == 0); 2997 CU_ASSERT(super->used_blobid_mask_len == 0); 2998 } 2999 3000 static void 3001 blob_set_xattrs(void) 3002 { 3003 struct spdk_blob_store *bs; 3004 struct spdk_bs_dev *dev; 3005 struct spdk_blob *blob; 3006 struct spdk_blob_opts opts; 3007 spdk_blob_id blobid; 3008 const void *value; 3009 size_t value_len; 3010 int rc; 3011 3012 dev = init_dev(); 3013 3014 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3015 CU_ASSERT(g_bserrno == 0); 3016 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3017 bs = g_bs; 3018 3019 /* Create blob with extra attributes */ 3020 spdk_blob_opts_init(&opts); 3021 3022 opts.xattrs.names = g_xattr_names; 3023 opts.xattrs.get_value = _get_xattr_value; 3024 opts.xattrs.count = 3; 3025 opts.xattrs.ctx = &g_ctx; 3026 3027 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3028 CU_ASSERT(g_bserrno == 0); 3029 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3030 blobid = g_blobid; 3031 3032 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3033 CU_ASSERT(g_bserrno == 0); 3034 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3035 blob = g_blob; 3036 3037 /* Get the xattrs */ 3038 value = NULL; 3039 3040 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 3041 CU_ASSERT(rc == 0); 3042 SPDK_CU_ASSERT_FATAL(value != NULL); 3043 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 3044 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 3045 3046 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 3047 CU_ASSERT(rc == 0); 3048 SPDK_CU_ASSERT_FATAL(value != NULL); 3049 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 3050 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 3051 3052 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 3053 CU_ASSERT(rc == 0); 3054 SPDK_CU_ASSERT_FATAL(value != NULL); 3055 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 3056 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 3057 3058 /* Try to get non existing attribute */ 3059 3060 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 3061 CU_ASSERT(rc == -ENOENT); 3062 3063 spdk_blob_close(blob, blob_op_complete, NULL); 3064 CU_ASSERT(g_bserrno == 0); 3065 blob = NULL; 3066 g_blob = NULL; 3067 g_blobid = SPDK_BLOBID_INVALID; 3068 3069 /* NULL callback */ 3070 spdk_blob_opts_init(&opts); 3071 opts.xattrs.names = g_xattr_names; 3072 opts.xattrs.get_value = NULL; 3073 opts.xattrs.count = 1; 3074 opts.xattrs.ctx = &g_ctx; 3075 3076 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3077 CU_ASSERT(g_bserrno == -EINVAL); 3078 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3079 3080 /* NULL values */ 3081 spdk_blob_opts_init(&opts); 3082 opts.xattrs.names = g_xattr_names; 3083 opts.xattrs.get_value = _get_xattr_value_null; 3084 opts.xattrs.count = 1; 3085 opts.xattrs.ctx = NULL; 3086 3087 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3088 CU_ASSERT(g_bserrno == -EINVAL); 3089 3090 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3091 CU_ASSERT(g_bserrno == 0); 3092 g_bs = NULL; 3093 3094 } 3095 3096 static void 3097 blob_thin_prov_alloc(void) 3098 { 3099 struct spdk_blob_store *bs; 3100 struct spdk_bs_dev *dev; 3101 struct spdk_blob *blob; 3102 struct spdk_blob_opts opts; 3103 spdk_blob_id blobid; 3104 uint64_t free_clusters; 3105 3106 dev = init_dev(); 3107 3108 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3109 CU_ASSERT(g_bserrno == 0); 3110 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3111 bs = g_bs; 3112 free_clusters = spdk_bs_free_cluster_count(bs); 3113 3114 /* Set blob as thin provisioned */ 3115 spdk_blob_opts_init(&opts); 3116 opts.thin_provision = true; 3117 3118 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3119 CU_ASSERT(g_bserrno == 0); 3120 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3121 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3122 blobid = g_blobid; 3123 3124 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3125 CU_ASSERT(g_bserrno == 0); 3126 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3127 blob = g_blob; 3128 3129 CU_ASSERT(blob->active.num_clusters == 0); 3130 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 3131 3132 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3133 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3134 CU_ASSERT(g_bserrno == 0); 3135 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3136 CU_ASSERT(blob->active.num_clusters == 5); 3137 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3138 3139 /* Shrink the blob to 3 clusters - still unallocated */ 3140 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 3141 CU_ASSERT(g_bserrno == 0); 3142 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3143 CU_ASSERT(blob->active.num_clusters == 3); 3144 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 3145 3146 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3147 CU_ASSERT(g_bserrno == 0); 3148 /* Sync must not change anything */ 3149 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3150 CU_ASSERT(blob->active.num_clusters == 3); 3151 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 3152 3153 spdk_blob_close(blob, blob_op_complete, NULL); 3154 CU_ASSERT(g_bserrno == 0); 3155 3156 /* Unload the blob store */ 3157 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3158 CU_ASSERT(g_bserrno == 0); 3159 g_bs = NULL; 3160 g_blob = NULL; 3161 g_blobid = 0; 3162 3163 /* Load an existing blob store */ 3164 dev = init_dev(); 3165 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3166 CU_ASSERT(g_bserrno == 0); 3167 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3168 3169 bs = g_bs; 3170 3171 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3172 CU_ASSERT(g_bserrno == 0); 3173 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3174 blob = g_blob; 3175 3176 /* Check that clusters allocation and size is still the same */ 3177 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3178 CU_ASSERT(blob->active.num_clusters == 3); 3179 3180 spdk_blob_close(blob, blob_op_complete, NULL); 3181 CU_ASSERT(g_bserrno == 0); 3182 3183 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3184 CU_ASSERT(g_bserrno == 0); 3185 3186 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3187 CU_ASSERT(g_bserrno == 0); 3188 g_bs = NULL; 3189 } 3190 3191 static void 3192 blob_insert_cluster_msg(void) 3193 { 3194 struct spdk_blob_store *bs; 3195 struct spdk_bs_dev *dev; 3196 struct spdk_blob *blob; 3197 struct spdk_blob_opts opts; 3198 spdk_blob_id blobid; 3199 uint64_t free_clusters; 3200 3201 dev = init_dev(); 3202 3203 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3204 CU_ASSERT(g_bserrno == 0); 3205 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3206 bs = g_bs; 3207 free_clusters = spdk_bs_free_cluster_count(bs); 3208 3209 /* Set blob as thin provisioned */ 3210 spdk_blob_opts_init(&opts); 3211 opts.thin_provision = true; 3212 opts.num_clusters = 4; 3213 3214 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3215 CU_ASSERT(g_bserrno == 0); 3216 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3217 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3218 blobid = g_blobid; 3219 3220 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3221 CU_ASSERT(g_bserrno == 0); 3222 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3223 blob = g_blob; 3224 3225 CU_ASSERT(blob->active.num_clusters == 4); 3226 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 3227 CU_ASSERT(blob->active.clusters[1] == 0); 3228 3229 _spdk_bs_claim_cluster(bs, 0xF); 3230 _spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL); 3231 3232 CU_ASSERT(blob->active.clusters[1] != 0); 3233 3234 spdk_blob_close(blob, blob_op_complete, NULL); 3235 CU_ASSERT(g_bserrno == 0); 3236 3237 /* Unload the blob store */ 3238 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3239 CU_ASSERT(g_bserrno == 0); 3240 g_bs = NULL; 3241 g_blob = NULL; 3242 g_blobid = 0; 3243 3244 /* Load an existing blob store */ 3245 dev = init_dev(); 3246 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3247 CU_ASSERT(g_bserrno == 0); 3248 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3249 3250 bs = g_bs; 3251 3252 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3253 CU_ASSERT(g_bserrno == 0); 3254 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3255 blob = g_blob; 3256 3257 CU_ASSERT(blob->active.clusters[1] != 0); 3258 3259 spdk_blob_close(blob, blob_op_complete, NULL); 3260 CU_ASSERT(g_bserrno == 0); 3261 3262 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3263 CU_ASSERT(g_bserrno == 0); 3264 3265 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3266 CU_ASSERT(g_bserrno == 0); 3267 g_bs = NULL; 3268 } 3269 3270 static void 3271 blob_thin_prov_rw(void) 3272 { 3273 static const uint8_t zero[10 * 4096] = { 0 }; 3274 struct spdk_blob_store *bs; 3275 struct spdk_bs_dev *dev; 3276 struct spdk_blob *blob; 3277 struct spdk_io_channel *channel; 3278 struct spdk_blob_opts opts; 3279 spdk_blob_id blobid; 3280 uint64_t free_clusters; 3281 uint8_t payload_read[10 * 4096]; 3282 uint8_t payload_write[10 * 4096]; 3283 3284 dev = init_dev(); 3285 3286 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3287 CU_ASSERT(g_bserrno == 0); 3288 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3289 bs = g_bs; 3290 free_clusters = spdk_bs_free_cluster_count(bs); 3291 3292 channel = spdk_bs_alloc_io_channel(bs); 3293 CU_ASSERT(channel != NULL); 3294 3295 spdk_blob_opts_init(&opts); 3296 opts.thin_provision = true; 3297 3298 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3299 CU_ASSERT(g_bserrno == 0); 3300 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3301 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3302 blobid = g_blobid; 3303 3304 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3305 CU_ASSERT(g_bserrno == 0); 3306 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3307 blob = g_blob; 3308 3309 CU_ASSERT(blob->active.num_clusters == 0); 3310 3311 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3312 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3313 CU_ASSERT(g_bserrno == 0); 3314 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3315 CU_ASSERT(blob->active.num_clusters == 5); 3316 3317 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3318 CU_ASSERT(g_bserrno == 0); 3319 /* Sync must not change anything */ 3320 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3321 CU_ASSERT(blob->active.num_clusters == 5); 3322 3323 /* Payload should be all zeros from unallocated clusters */ 3324 memset(payload_read, 0xFF, sizeof(payload_read)); 3325 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3326 CU_ASSERT(g_bserrno == 0); 3327 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3328 3329 memset(payload_write, 0xE5, sizeof(payload_write)); 3330 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3331 CU_ASSERT(g_bserrno == 0); 3332 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3333 3334 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3335 CU_ASSERT(g_bserrno == 0); 3336 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3337 3338 spdk_blob_close(blob, blob_op_complete, NULL); 3339 CU_ASSERT(g_bserrno == 0); 3340 3341 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3342 CU_ASSERT(g_bserrno == 0); 3343 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3344 3345 spdk_bs_free_io_channel(channel); 3346 3347 /* Unload the blob store */ 3348 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3349 CU_ASSERT(g_bserrno == 0); 3350 g_bs = NULL; 3351 g_blob = NULL; 3352 g_blobid = 0; 3353 } 3354 3355 static void 3356 blob_thin_prov_rw_iov(void) 3357 { 3358 static const uint8_t zero[10 * 4096] = { 0 }; 3359 struct spdk_blob_store *bs; 3360 struct spdk_bs_dev *dev; 3361 struct spdk_blob *blob; 3362 struct spdk_io_channel *channel; 3363 struct spdk_blob_opts opts; 3364 spdk_blob_id blobid; 3365 uint64_t free_clusters; 3366 uint8_t payload_read[10 * 4096]; 3367 uint8_t payload_write[10 * 4096]; 3368 struct iovec iov_read[3]; 3369 struct iovec iov_write[3]; 3370 3371 dev = init_dev(); 3372 3373 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3374 CU_ASSERT(g_bserrno == 0); 3375 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3376 bs = g_bs; 3377 free_clusters = spdk_bs_free_cluster_count(bs); 3378 3379 channel = spdk_bs_alloc_io_channel(bs); 3380 CU_ASSERT(channel != NULL); 3381 3382 spdk_blob_opts_init(&opts); 3383 opts.thin_provision = true; 3384 3385 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3386 CU_ASSERT(g_bserrno == 0); 3387 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3388 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3389 blobid = g_blobid; 3390 3391 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3392 CU_ASSERT(g_bserrno == 0); 3393 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3394 blob = g_blob; 3395 3396 CU_ASSERT(blob->active.num_clusters == 0); 3397 3398 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3399 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3400 CU_ASSERT(g_bserrno == 0); 3401 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3402 CU_ASSERT(blob->active.num_clusters == 5); 3403 3404 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3405 CU_ASSERT(g_bserrno == 0); 3406 /* Sync must not change anything */ 3407 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3408 CU_ASSERT(blob->active.num_clusters == 5); 3409 3410 /* Payload should be all zeros from unallocated clusters */ 3411 memset(payload_read, 0xAA, sizeof(payload_read)); 3412 iov_read[0].iov_base = payload_read; 3413 iov_read[0].iov_len = 3 * 4096; 3414 iov_read[1].iov_base = payload_read + 3 * 4096; 3415 iov_read[1].iov_len = 4 * 4096; 3416 iov_read[2].iov_base = payload_read + 7 * 4096; 3417 iov_read[2].iov_len = 3 * 4096; 3418 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3419 CU_ASSERT(g_bserrno == 0); 3420 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3421 3422 memset(payload_write, 0xE5, sizeof(payload_write)); 3423 iov_write[0].iov_base = payload_write; 3424 iov_write[0].iov_len = 1 * 4096; 3425 iov_write[1].iov_base = payload_write + 1 * 4096; 3426 iov_write[1].iov_len = 5 * 4096; 3427 iov_write[2].iov_base = payload_write + 6 * 4096; 3428 iov_write[2].iov_len = 4 * 4096; 3429 3430 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 3431 CU_ASSERT(g_bserrno == 0); 3432 3433 memset(payload_read, 0xAA, sizeof(payload_read)); 3434 iov_read[0].iov_base = payload_read; 3435 iov_read[0].iov_len = 3 * 4096; 3436 iov_read[1].iov_base = payload_read + 3 * 4096; 3437 iov_read[1].iov_len = 4 * 4096; 3438 iov_read[2].iov_base = payload_read + 7 * 4096; 3439 iov_read[2].iov_len = 3 * 4096; 3440 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3441 CU_ASSERT(g_bserrno == 0); 3442 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3443 3444 spdk_blob_close(blob, blob_op_complete, NULL); 3445 CU_ASSERT(g_bserrno == 0); 3446 3447 spdk_bs_free_io_channel(channel); 3448 3449 /* Unload the blob store */ 3450 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3451 CU_ASSERT(g_bserrno == 0); 3452 g_bs = NULL; 3453 g_blob = NULL; 3454 g_blobid = 0; 3455 } 3456 3457 struct iter_ctx { 3458 int current_iter; 3459 spdk_blob_id blobid[4]; 3460 }; 3461 3462 static void 3463 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 3464 { 3465 struct iter_ctx *iter_ctx = arg; 3466 spdk_blob_id blobid; 3467 3468 CU_ASSERT(bserrno == 0); 3469 blobid = spdk_blob_get_id(blob); 3470 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 3471 } 3472 3473 static void 3474 bs_load_iter(void) 3475 { 3476 struct spdk_bs_dev *dev; 3477 struct iter_ctx iter_ctx = { 0 }; 3478 struct spdk_blob *blob; 3479 int i, rc; 3480 struct spdk_bs_opts opts; 3481 3482 dev = init_dev(); 3483 spdk_bs_opts_init(&opts); 3484 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3485 3486 /* Initialize a new blob store */ 3487 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3488 CU_ASSERT(g_bserrno == 0); 3489 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3490 3491 for (i = 0; i < 4; i++) { 3492 g_bserrno = -1; 3493 g_blobid = SPDK_BLOBID_INVALID; 3494 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3495 CU_ASSERT(g_bserrno == 0); 3496 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3497 iter_ctx.blobid[i] = g_blobid; 3498 3499 g_bserrno = -1; 3500 g_blob = NULL; 3501 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 3502 CU_ASSERT(g_bserrno == 0); 3503 CU_ASSERT(g_blob != NULL); 3504 blob = g_blob; 3505 3506 /* Just save the blobid as an xattr for testing purposes. */ 3507 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 3508 CU_ASSERT(rc == 0); 3509 3510 /* Resize the blob */ 3511 spdk_blob_resize(blob, i, blob_op_complete, NULL); 3512 CU_ASSERT(g_bserrno == 0); 3513 3514 spdk_blob_close(blob, blob_op_complete, NULL); 3515 CU_ASSERT(g_bserrno == 0); 3516 } 3517 3518 g_bserrno = -1; 3519 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3520 CU_ASSERT(g_bserrno == 0); 3521 3522 dev = init_dev(); 3523 spdk_bs_opts_init(&opts); 3524 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3525 opts.iter_cb_fn = test_iter; 3526 opts.iter_cb_arg = &iter_ctx; 3527 3528 /* Test blob iteration during load after a clean shutdown. */ 3529 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3530 CU_ASSERT(g_bserrno == 0); 3531 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3532 3533 /* Dirty shutdown */ 3534 _spdk_bs_free(g_bs); 3535 3536 dev = init_dev(); 3537 spdk_bs_opts_init(&opts); 3538 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3539 opts.iter_cb_fn = test_iter; 3540 iter_ctx.current_iter = 0; 3541 opts.iter_cb_arg = &iter_ctx; 3542 3543 /* Test blob iteration during load after a dirty shutdown. */ 3544 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3545 CU_ASSERT(g_bserrno == 0); 3546 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3547 3548 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3549 CU_ASSERT(g_bserrno == 0); 3550 g_bs = NULL; 3551 } 3552 3553 static void 3554 blob_snapshot_rw(void) 3555 { 3556 static const uint8_t zero[10 * 4096] = { 0 }; 3557 struct spdk_blob_store *bs; 3558 struct spdk_bs_dev *dev; 3559 struct spdk_blob *blob, *snapshot; 3560 struct spdk_io_channel *channel; 3561 struct spdk_blob_opts opts; 3562 spdk_blob_id blobid, snapshotid; 3563 uint64_t free_clusters; 3564 uint8_t payload_read[10 * 4096]; 3565 uint8_t payload_write[10 * 4096]; 3566 3567 dev = init_dev(); 3568 3569 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3570 CU_ASSERT(g_bserrno == 0); 3571 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3572 bs = g_bs; 3573 free_clusters = spdk_bs_free_cluster_count(bs); 3574 3575 channel = spdk_bs_alloc_io_channel(bs); 3576 CU_ASSERT(channel != NULL); 3577 3578 spdk_blob_opts_init(&opts); 3579 opts.thin_provision = true; 3580 opts.num_clusters = 5; 3581 3582 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3583 CU_ASSERT(g_bserrno == 0); 3584 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3585 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3586 blobid = g_blobid; 3587 3588 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3589 CU_ASSERT(g_bserrno == 0); 3590 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3591 blob = g_blob; 3592 3593 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3594 3595 memset(payload_read, 0xFF, sizeof(payload_read)); 3596 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3597 CU_ASSERT(g_bserrno == 0); 3598 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3599 3600 memset(payload_write, 0xE5, sizeof(payload_write)); 3601 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3602 CU_ASSERT(g_bserrno == 0); 3603 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3604 3605 /* Create snapshot from blob */ 3606 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 3607 CU_ASSERT(g_bserrno == 0); 3608 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3609 snapshotid = g_blobid; 3610 3611 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 3612 CU_ASSERT(g_bserrno == 0); 3613 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3614 snapshot = g_blob; 3615 CU_ASSERT(snapshot->data_ro == true) 3616 CU_ASSERT(snapshot->md_ro == true) 3617 3618 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 3619 3620 memset(payload_write, 0xAA, sizeof(payload_write)); 3621 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3622 CU_ASSERT(g_bserrno == 0); 3623 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3624 3625 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3626 CU_ASSERT(g_bserrno == 0); 3627 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3628 3629 /* Data on snapshot should not change after write to clone */ 3630 memset(payload_write, 0xE5, sizeof(payload_write)); 3631 spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL); 3632 CU_ASSERT(g_bserrno == 0); 3633 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3634 3635 spdk_blob_close(blob, blob_op_complete, NULL); 3636 CU_ASSERT(g_bserrno == 0); 3637 3638 spdk_blob_close(snapshot, blob_op_complete, NULL); 3639 CU_ASSERT(g_bserrno == 0); 3640 3641 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3642 CU_ASSERT(g_bserrno == 0); 3643 3644 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 3645 CU_ASSERT(g_bserrno == 0); 3646 3647 spdk_bs_free_io_channel(channel); 3648 3649 /* Unload the blob store */ 3650 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3651 CU_ASSERT(g_bserrno == 0); 3652 g_bs = NULL; 3653 g_blob = NULL; 3654 g_blobid = 0; 3655 } 3656 3657 static void 3658 blob_snapshot_rw_iov(void) 3659 { 3660 static const uint8_t zero[10 * 4096] = { 0 }; 3661 struct spdk_blob_store *bs; 3662 struct spdk_bs_dev *dev; 3663 struct spdk_blob *blob, *snapshot; 3664 struct spdk_io_channel *channel; 3665 struct spdk_blob_opts opts; 3666 spdk_blob_id blobid, snapshotid; 3667 uint64_t free_clusters; 3668 uint8_t payload_read[10 * 4096]; 3669 uint8_t payload_write[10 * 4096]; 3670 struct iovec iov_read[3]; 3671 struct iovec iov_write[3]; 3672 3673 dev = init_dev(); 3674 3675 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3676 CU_ASSERT(g_bserrno == 0); 3677 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3678 bs = g_bs; 3679 free_clusters = spdk_bs_free_cluster_count(bs); 3680 3681 channel = spdk_bs_alloc_io_channel(bs); 3682 CU_ASSERT(channel != NULL); 3683 3684 spdk_blob_opts_init(&opts); 3685 opts.thin_provision = true; 3686 opts.num_clusters = 5; 3687 3688 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3689 CU_ASSERT(g_bserrno == 0); 3690 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3691 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3692 blobid = g_blobid; 3693 3694 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3695 CU_ASSERT(g_bserrno == 0); 3696 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3697 blob = g_blob; 3698 3699 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3700 3701 /* Create snapshot from blob */ 3702 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 3703 CU_ASSERT(g_bserrno == 0); 3704 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3705 snapshotid = g_blobid; 3706 3707 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 3708 CU_ASSERT(g_bserrno == 0); 3709 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3710 snapshot = g_blob; 3711 CU_ASSERT(snapshot->data_ro == true) 3712 CU_ASSERT(snapshot->md_ro == true) 3713 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 3714 3715 /* Payload should be all zeros from unallocated clusters */ 3716 memset(payload_read, 0xAA, sizeof(payload_read)); 3717 iov_read[0].iov_base = payload_read; 3718 iov_read[0].iov_len = 3 * 4096; 3719 iov_read[1].iov_base = payload_read + 3 * 4096; 3720 iov_read[1].iov_len = 4 * 4096; 3721 iov_read[2].iov_base = payload_read + 7 * 4096; 3722 iov_read[2].iov_len = 3 * 4096; 3723 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3724 CU_ASSERT(g_bserrno == 0); 3725 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3726 3727 memset(payload_write, 0xE5, sizeof(payload_write)); 3728 iov_write[0].iov_base = payload_write; 3729 iov_write[0].iov_len = 1 * 4096; 3730 iov_write[1].iov_base = payload_write + 1 * 4096; 3731 iov_write[1].iov_len = 5 * 4096; 3732 iov_write[2].iov_base = payload_write + 6 * 4096; 3733 iov_write[2].iov_len = 4 * 4096; 3734 3735 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 3736 CU_ASSERT(g_bserrno == 0); 3737 3738 memset(payload_read, 0xAA, sizeof(payload_read)); 3739 iov_read[0].iov_base = payload_read; 3740 iov_read[0].iov_len = 3 * 4096; 3741 iov_read[1].iov_base = payload_read + 3 * 4096; 3742 iov_read[1].iov_len = 4 * 4096; 3743 iov_read[2].iov_base = payload_read + 7 * 4096; 3744 iov_read[2].iov_len = 3 * 4096; 3745 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3746 CU_ASSERT(g_bserrno == 0); 3747 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3748 3749 spdk_blob_close(blob, blob_op_complete, NULL); 3750 CU_ASSERT(g_bserrno == 0); 3751 3752 spdk_blob_close(snapshot, blob_op_complete, NULL); 3753 CU_ASSERT(g_bserrno == 0); 3754 3755 spdk_bs_free_io_channel(channel); 3756 3757 /* Unload the blob store */ 3758 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3759 CU_ASSERT(g_bserrno == 0); 3760 g_bs = NULL; 3761 g_blob = NULL; 3762 g_blobid = 0; 3763 } 3764 3765 /** 3766 * Snapshot-clones relation test 3767 * 3768 * snapshot 3769 * | 3770 * +----+----+ 3771 * | | 3772 * blob clone 3773 * | 3774 * clone2 3775 */ 3776 static void 3777 blob_relations(void) 3778 { 3779 struct spdk_blob_store *bs; 3780 struct spdk_bs_dev *dev; 3781 struct spdk_bs_opts bs_opts; 3782 struct spdk_blob_opts opts; 3783 struct spdk_blob *blob, *snapshot, *clone, *clone2; 3784 spdk_blob_id blobid, cloneid, snapshotid, cloneid2; 3785 int rc; 3786 size_t count; 3787 spdk_blob_id ids[10]; 3788 3789 dev = init_dev(); 3790 spdk_bs_opts_init(&bs_opts); 3791 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 3792 3793 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 3794 CU_ASSERT(g_bserrno == 0); 3795 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3796 bs = g_bs; 3797 3798 /* 1. Create blob with 10 clusters */ 3799 3800 spdk_blob_opts_init(&opts); 3801 opts.num_clusters = 10; 3802 3803 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3804 CU_ASSERT(g_bserrno == 0); 3805 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3806 blobid = g_blobid; 3807 3808 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3809 CU_ASSERT(g_bserrno == 0); 3810 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3811 blob = g_blob; 3812 3813 CU_ASSERT(!spdk_blob_is_read_only(blob)); 3814 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 3815 CU_ASSERT(!spdk_blob_is_clone(blob)); 3816 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob)); 3817 3818 /* blob should not have underlying snapshot nor clones */ 3819 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 3820 count = SPDK_COUNTOF(ids); 3821 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 3822 CU_ASSERT(rc == 0); 3823 CU_ASSERT(count == 0); 3824 3825 3826 /* 2. Create snapshot */ 3827 3828 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 3829 CU_ASSERT(g_bserrno == 0); 3830 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3831 snapshotid = g_blobid; 3832 3833 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 3834 CU_ASSERT(g_bserrno == 0); 3835 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3836 snapshot = g_blob; 3837 3838 CU_ASSERT(spdk_blob_is_read_only(snapshot)); 3839 CU_ASSERT(spdk_blob_is_snapshot(snapshot)); 3840 CU_ASSERT(!spdk_blob_is_clone(snapshot)); 3841 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 3842 3843 /* Check if original blob is converted to the clone of snapshot */ 3844 CU_ASSERT(!spdk_blob_is_read_only(blob)); 3845 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 3846 CU_ASSERT(spdk_blob_is_clone(blob)); 3847 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 3848 3849 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 3850 3851 count = SPDK_COUNTOF(ids); 3852 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 3853 CU_ASSERT(rc == 0); 3854 CU_ASSERT(count == 1); 3855 CU_ASSERT(ids[0] == blobid); 3856 3857 3858 /* 3. Create clone from snapshot */ 3859 3860 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 3861 CU_ASSERT(g_bserrno == 0); 3862 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3863 cloneid = g_blobid; 3864 3865 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 3866 CU_ASSERT(g_bserrno == 0); 3867 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3868 clone = g_blob; 3869 3870 CU_ASSERT(!spdk_blob_is_read_only(clone)); 3871 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 3872 CU_ASSERT(spdk_blob_is_clone(clone)); 3873 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 3874 3875 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 3876 3877 count = SPDK_COUNTOF(ids); 3878 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 3879 CU_ASSERT(rc == 0); 3880 CU_ASSERT(count == 0); 3881 3882 /* Check if clone is on the snapshot's list */ 3883 count = SPDK_COUNTOF(ids); 3884 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 3885 CU_ASSERT(rc == 0); 3886 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 3887 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 3888 3889 3890 /* 4. Try to create clone from read only blob */ 3891 3892 /* Mark blob as read only */ 3893 spdk_blob_set_read_only(blob); 3894 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3895 CU_ASSERT(g_bserrno == 0); 3896 3897 /* Check if previously created blob is read only clone */ 3898 CU_ASSERT(spdk_blob_is_read_only(blob)); 3899 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 3900 CU_ASSERT(spdk_blob_is_clone(blob)); 3901 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 3902 3903 /* Create clone from read only blob */ 3904 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 3905 CU_ASSERT(g_bserrno == 0); 3906 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3907 cloneid2 = g_blobid; 3908 3909 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 3910 CU_ASSERT(g_bserrno == 0); 3911 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3912 clone2 = g_blob; 3913 3914 CU_ASSERT(!spdk_blob_is_read_only(clone2)); 3915 CU_ASSERT(!spdk_blob_is_snapshot(clone2)); 3916 CU_ASSERT(spdk_blob_is_clone(clone2)); 3917 CU_ASSERT(spdk_blob_is_thin_provisioned(clone2)); 3918 3919 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 3920 3921 count = SPDK_COUNTOF(ids); 3922 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 3923 CU_ASSERT(rc == 0); 3924 3925 CU_ASSERT(count == 1); 3926 CU_ASSERT(ids[0] == cloneid2); 3927 3928 /* Close blobs */ 3929 3930 spdk_blob_close(clone2, blob_op_complete, NULL); 3931 CU_ASSERT(g_bserrno == 0); 3932 3933 spdk_blob_close(blob, blob_op_complete, NULL); 3934 CU_ASSERT(g_bserrno == 0); 3935 3936 spdk_blob_close(clone, blob_op_complete, NULL); 3937 CU_ASSERT(g_bserrno == 0); 3938 3939 spdk_blob_close(snapshot, blob_op_complete, NULL); 3940 CU_ASSERT(g_bserrno == 0); 3941 3942 /* Try to delete snapshot with created clones */ 3943 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 3944 CU_ASSERT(g_bserrno != 0); 3945 3946 spdk_bs_unload(bs, bs_op_complete, NULL); 3947 CU_ASSERT(g_bserrno == 0); 3948 g_bs = NULL; 3949 3950 /* Load an existing blob store */ 3951 dev = init_dev(); 3952 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 3953 3954 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3955 CU_ASSERT(g_bserrno == 0); 3956 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3957 bs = g_bs; 3958 3959 3960 /* NULL ids array should return number of clones in count */ 3961 count = SPDK_COUNTOF(ids); 3962 rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count); 3963 CU_ASSERT(rc == -ENOMEM); 3964 CU_ASSERT(count == 2); 3965 3966 /* incorrect array size */ 3967 count = 1; 3968 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 3969 CU_ASSERT(rc == -ENOMEM); 3970 CU_ASSERT(count == 2); 3971 3972 3973 /* Verify structure of loaded blob store */ 3974 3975 /* snapshot */ 3976 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 3977 3978 count = SPDK_COUNTOF(ids); 3979 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 3980 CU_ASSERT(rc == 0); 3981 CU_ASSERT(count == 2); 3982 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 3983 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 3984 3985 /* blob */ 3986 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 3987 count = SPDK_COUNTOF(ids); 3988 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 3989 CU_ASSERT(rc == 0); 3990 CU_ASSERT(count == 1); 3991 CU_ASSERT(ids[0] == cloneid2); 3992 3993 /* clone */ 3994 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 3995 count = SPDK_COUNTOF(ids); 3996 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 3997 CU_ASSERT(rc == 0); 3998 CU_ASSERT(count == 0); 3999 4000 /* clone2 */ 4001 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 4002 count = SPDK_COUNTOF(ids); 4003 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 4004 CU_ASSERT(rc == 0); 4005 CU_ASSERT(count == 0); 4006 4007 /* Try to delete all blobs */ 4008 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 4009 CU_ASSERT(g_bserrno == 0); 4010 4011 /* Try to delete snapshot with clones */ 4012 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4013 CU_ASSERT(g_bserrno != 0); 4014 4015 /* Try to delete ro blob with clones */ 4016 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4017 CU_ASSERT(g_bserrno != 0); 4018 4019 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 4020 CU_ASSERT(g_bserrno == 0); 4021 4022 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4023 CU_ASSERT(g_bserrno == 0); 4024 4025 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4026 CU_ASSERT(g_bserrno == 0); 4027 4028 spdk_bs_unload(bs, bs_op_complete, NULL); 4029 CU_ASSERT(g_bserrno == 0); 4030 4031 g_bs = NULL; 4032 } 4033 4034 int main(int argc, char **argv) 4035 { 4036 CU_pSuite suite = NULL; 4037 unsigned int num_failures; 4038 4039 if (CU_initialize_registry() != CUE_SUCCESS) { 4040 return CU_get_error(); 4041 } 4042 4043 suite = CU_add_suite("blob", NULL, NULL); 4044 if (suite == NULL) { 4045 CU_cleanup_registry(); 4046 return CU_get_error(); 4047 } 4048 4049 if ( 4050 CU_add_test(suite, "blob_init", blob_init) == NULL || 4051 CU_add_test(suite, "blob_open", blob_open) == NULL || 4052 CU_add_test(suite, "blob_create", blob_create) == NULL || 4053 CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL || 4054 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 4055 CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL || 4056 CU_add_test(suite, "blob_clone", blob_clone) == NULL || 4057 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 4058 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 4059 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 4060 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 4061 CU_add_test(suite, "blob_super", blob_super) == NULL || 4062 CU_add_test(suite, "blob_write", blob_write) == NULL || 4063 CU_add_test(suite, "blob_read", blob_read) == NULL || 4064 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 4065 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 4066 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 4067 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 4068 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 4069 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 4070 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 4071 CU_add_test(suite, "bs_load", bs_load) == NULL || 4072 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 4073 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 4074 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 4075 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 4076 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 4077 CU_add_test(suite, "bs_type", bs_type) == NULL || 4078 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 4079 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 4080 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 4081 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 4082 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 4083 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 4084 CU_add_test(suite, "bs_version", bs_version) == NULL || 4085 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 4086 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 4087 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 4088 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 4089 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL || 4090 CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL || 4091 CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL || 4092 CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL || 4093 CU_add_test(suite, "blob_relations", blob_relations) == NULL 4094 ) { 4095 CU_cleanup_registry(); 4096 return CU_get_error(); 4097 } 4098 4099 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 4100 spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 4101 CU_basic_set_mode(CU_BRM_VERBOSE); 4102 CU_basic_run_tests(); 4103 num_failures = CU_get_number_of_failures(); 4104 CU_cleanup_registry(); 4105 spdk_free_thread(); 4106 free(g_dev_buffer); 4107 return num_failures; 4108 } 4109