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 39 #include "lib/test_env.c" 40 #include "../bs_dev_common.c" 41 #include "blob/blobstore.c" 42 #include "blob/request.c" 43 #include "blob/zeroes.c" 44 #include "blob/blob_bs_dev.c" 45 46 struct spdk_blob_store *g_bs; 47 spdk_blob_id g_blobid; 48 struct spdk_blob *g_blob; 49 int g_bserrno; 50 struct spdk_xattr_names *g_names; 51 int g_done; 52 char *g_xattr_names[] = {"first", "second", "third"}; 53 char *g_xattr_values[] = {"one", "two", "three"}; 54 uint64_t g_ctx = 1729; 55 56 bool g_scheduler_delay = false; 57 58 struct scheduled_ops { 59 spdk_thread_fn fn; 60 void *ctx; 61 62 TAILQ_ENTRY(scheduled_ops) ops_queue; 63 }; 64 65 static TAILQ_HEAD(, scheduled_ops) g_scheduled_ops = TAILQ_HEAD_INITIALIZER(g_scheduled_ops); 66 67 struct spdk_bs_super_block_ver1 { 68 uint8_t signature[8]; 69 uint32_t version; 70 uint32_t length; 71 uint32_t clean; /* If there was a clean shutdown, this is 1. */ 72 spdk_blob_id super_blob; 73 74 uint32_t cluster_size; /* In bytes */ 75 76 uint32_t used_page_mask_start; /* Offset from beginning of disk, in pages */ 77 uint32_t used_page_mask_len; /* Count, in pages */ 78 79 uint32_t used_cluster_mask_start; /* Offset from beginning of disk, in pages */ 80 uint32_t used_cluster_mask_len; /* Count, in pages */ 81 82 uint32_t md_start; /* Offset from beginning of disk, in pages */ 83 uint32_t md_len; /* Count, in pages */ 84 85 uint8_t reserved[4036]; 86 uint32_t crc; 87 } __attribute__((packed)); 88 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size"); 89 90 static void 91 _bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) 92 { 93 if (g_scheduler_delay) { 94 struct scheduled_ops *ops = calloc(1, sizeof(*ops)); 95 96 SPDK_CU_ASSERT_FATAL(ops != NULL); 97 ops->fn = fn; 98 ops->ctx = ctx; 99 TAILQ_INSERT_TAIL(&g_scheduled_ops, ops, ops_queue); 100 } else { 101 fn(ctx); 102 } 103 } 104 105 #if 0 106 static void 107 _bs_flush_scheduler(void) 108 { 109 struct scheduled_ops *ops; 110 111 while (!TAILQ_EMPTY(&g_scheduled_ops)) { 112 ops = TAILQ_FIRST(&g_scheduled_ops); 113 TAILQ_REMOVE(&g_scheduled_ops, ops, ops_queue); 114 ops->fn(ops->ctx); 115 free(ops); 116 } 117 } 118 #endif 119 120 static void 121 bs_op_complete(void *cb_arg, int bserrno) 122 { 123 g_bserrno = bserrno; 124 } 125 126 static void 127 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 128 int bserrno) 129 { 130 g_bs = bs; 131 g_bserrno = bserrno; 132 } 133 134 static void 135 blob_op_complete(void *cb_arg, int bserrno) 136 { 137 g_bserrno = bserrno; 138 } 139 140 static void 141 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 142 { 143 g_blobid = blobid; 144 g_bserrno = bserrno; 145 } 146 147 static void 148 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 149 { 150 g_blob = blb; 151 g_bserrno = bserrno; 152 } 153 154 static void 155 blob_init(void) 156 { 157 struct spdk_bs_dev *dev; 158 159 dev = init_dev(); 160 161 /* should fail for an unsupported blocklen */ 162 dev->blocklen = 500; 163 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 164 CU_ASSERT(g_bserrno == -EINVAL); 165 166 dev = init_dev(); 167 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 168 CU_ASSERT(g_bserrno == 0); 169 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 170 171 spdk_bs_unload(g_bs, bs_op_complete, NULL); 172 CU_ASSERT(g_bserrno == 0); 173 g_bs = NULL; 174 } 175 176 static void 177 blob_super(void) 178 { 179 struct spdk_blob_store *bs; 180 struct spdk_bs_dev *dev; 181 spdk_blob_id blobid; 182 183 dev = init_dev(); 184 185 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 186 CU_ASSERT(g_bserrno == 0); 187 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 188 bs = g_bs; 189 190 /* Get the super blob without having set one */ 191 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 192 CU_ASSERT(g_bserrno == -ENOENT); 193 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 194 195 /* Create a blob */ 196 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 197 CU_ASSERT(g_bserrno == 0); 198 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 199 blobid = g_blobid; 200 201 /* Set the blob as the super blob */ 202 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 203 CU_ASSERT(g_bserrno == 0); 204 205 /* Get the super blob */ 206 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 207 CU_ASSERT(g_bserrno == 0); 208 CU_ASSERT(blobid == g_blobid); 209 210 spdk_bs_unload(g_bs, bs_op_complete, NULL); 211 CU_ASSERT(g_bserrno == 0); 212 g_bs = NULL; 213 } 214 215 static void 216 blob_open(void) 217 { 218 struct spdk_blob_store *bs; 219 struct spdk_bs_dev *dev; 220 struct spdk_blob *blob; 221 spdk_blob_id blobid, blobid2; 222 223 dev = init_dev(); 224 225 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 226 CU_ASSERT(g_bserrno == 0); 227 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 228 bs = g_bs; 229 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 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 236 CU_ASSERT(g_bserrno == 0); 237 CU_ASSERT(g_blob != NULL); 238 blob = g_blob; 239 240 blobid2 = spdk_blob_get_id(blob); 241 CU_ASSERT(blobid == blobid2); 242 243 /* Try to open file again. It should return success. */ 244 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 245 CU_ASSERT(g_bserrno == 0); 246 CU_ASSERT(blob == g_blob); 247 248 spdk_blob_close(blob, blob_op_complete, NULL); 249 CU_ASSERT(g_bserrno == 0); 250 251 /* 252 * Close the file a second time, releasing the second reference. This 253 * should succeed. 254 */ 255 blob = g_blob; 256 spdk_blob_close(blob, blob_op_complete, NULL); 257 CU_ASSERT(g_bserrno == 0); 258 259 /* 260 * Try to open file again. It should succeed. This tests the case 261 * where the file is opened, closed, then re-opened again. 262 */ 263 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 264 CU_ASSERT(g_bserrno == 0); 265 CU_ASSERT(g_blob != NULL); 266 blob = g_blob; 267 268 spdk_blob_close(blob, blob_op_complete, NULL); 269 CU_ASSERT(g_bserrno == 0); 270 271 spdk_bs_unload(g_bs, bs_op_complete, NULL); 272 CU_ASSERT(g_bserrno == 0); 273 g_bs = NULL; 274 } 275 276 static void 277 blob_create(void) 278 { 279 struct spdk_blob_store *bs; 280 struct spdk_bs_dev *dev; 281 struct spdk_blob *blob; 282 struct spdk_blob_opts opts; 283 spdk_blob_id blobid; 284 285 dev = init_dev(); 286 287 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 288 CU_ASSERT(g_bserrno == 0); 289 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 290 bs = g_bs; 291 292 /* Create blob with 10 clusters */ 293 294 spdk_blob_opts_init(&opts); 295 opts.num_clusters = 10; 296 297 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 298 CU_ASSERT(g_bserrno == 0); 299 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 300 blobid = g_blobid; 301 302 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 303 CU_ASSERT(g_bserrno == 0); 304 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 305 blob = g_blob; 306 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 307 308 spdk_blob_close(blob, blob_op_complete, NULL); 309 CU_ASSERT(g_bserrno == 0); 310 311 /* Create blob with 0 clusters */ 312 313 spdk_blob_opts_init(&opts); 314 opts.num_clusters = 0; 315 316 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 317 CU_ASSERT(g_bserrno == 0); 318 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 319 blobid = g_blobid; 320 321 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 322 CU_ASSERT(g_bserrno == 0); 323 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 324 blob = g_blob; 325 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 326 327 spdk_blob_close(blob, blob_op_complete, NULL); 328 CU_ASSERT(g_bserrno == 0); 329 330 /* Create blob with default options (opts == NULL) */ 331 332 spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL); 333 CU_ASSERT(g_bserrno == 0); 334 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 335 blobid = g_blobid; 336 337 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 338 CU_ASSERT(g_bserrno == 0); 339 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 340 blob = g_blob; 341 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 342 343 spdk_blob_close(blob, blob_op_complete, NULL); 344 CU_ASSERT(g_bserrno == 0); 345 346 /* Try to create blob with size larger than blobstore */ 347 348 spdk_blob_opts_init(&opts); 349 opts.num_clusters = bs->total_clusters + 1; 350 351 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 352 CU_ASSERT(g_bserrno == -ENOSPC); 353 354 spdk_bs_unload(g_bs, bs_op_complete, NULL); 355 CU_ASSERT(g_bserrno == 0); 356 g_bs = NULL; 357 358 } 359 360 static void 361 blob_thin_provision(void) 362 { 363 struct spdk_blob_store *bs; 364 struct spdk_bs_dev *dev; 365 struct spdk_blob *blob; 366 struct spdk_blob_opts opts; 367 struct spdk_bs_opts bs_opts; 368 spdk_blob_id blobid; 369 370 dev = init_dev(); 371 spdk_bs_opts_init(&bs_opts); 372 strncpy(bs_opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 373 374 /* Initialize a new blob store */ 375 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 376 CU_ASSERT(g_bserrno == 0); 377 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 378 379 bs = g_bs; 380 381 /* Create blob with thin provisioning enabled */ 382 383 spdk_blob_opts_init(&opts); 384 opts.thin_provision = true; 385 opts.num_clusters = 10; 386 387 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 388 CU_ASSERT(g_bserrno == 0); 389 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 390 blobid = g_blobid; 391 392 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 393 CU_ASSERT(g_bserrno == 0); 394 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 395 blob = g_blob; 396 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 397 398 spdk_blob_close(blob, blob_op_complete, NULL); 399 CU_ASSERT(g_bserrno == 0); 400 401 spdk_bs_unload(g_bs, bs_op_complete, NULL); 402 CU_ASSERT(g_bserrno == 0); 403 g_bs = NULL; 404 405 /* Load an existing blob store and check if invalid_flags is set */ 406 dev = init_dev(); 407 strncpy(bs_opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 408 spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL); 409 CU_ASSERT(g_bserrno == 0); 410 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 411 412 bs = g_bs; 413 414 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 415 CU_ASSERT(g_bserrno == 0); 416 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 417 blob = g_blob; 418 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 419 420 spdk_blob_close(blob, blob_op_complete, NULL); 421 CU_ASSERT(g_bserrno == 0); 422 423 spdk_bs_unload(g_bs, bs_op_complete, NULL); 424 CU_ASSERT(g_bserrno == 0); 425 g_bs = NULL; 426 } 427 428 static void 429 blob_delete(void) 430 { 431 struct spdk_blob_store *bs; 432 struct spdk_bs_dev *dev; 433 spdk_blob_id blobid; 434 435 dev = init_dev(); 436 437 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 438 CU_ASSERT(g_bserrno == 0); 439 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 440 bs = g_bs; 441 442 /* Create a blob and then delete it. */ 443 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 444 CU_ASSERT(g_bserrno == 0); 445 CU_ASSERT(g_blobid > 0); 446 blobid = g_blobid; 447 448 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 449 CU_ASSERT(g_bserrno == 0); 450 451 /* Try to open the blob */ 452 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 453 CU_ASSERT(g_bserrno == -ENOENT); 454 455 spdk_bs_unload(g_bs, bs_op_complete, NULL); 456 CU_ASSERT(g_bserrno == 0); 457 g_bs = NULL; 458 } 459 460 static void 461 blob_resize(void) 462 { 463 struct spdk_blob_store *bs; 464 struct spdk_bs_dev *dev; 465 struct spdk_blob *blob; 466 spdk_blob_id blobid; 467 uint64_t free_clusters; 468 int rc; 469 470 dev = init_dev(); 471 472 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 473 CU_ASSERT(g_bserrno == 0); 474 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 475 bs = g_bs; 476 free_clusters = spdk_bs_free_cluster_count(bs); 477 478 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 479 CU_ASSERT(g_bserrno == 0); 480 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 481 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 482 blobid = g_blobid; 483 484 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 485 CU_ASSERT(g_bserrno == 0); 486 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 487 blob = g_blob; 488 489 /* Confirm that resize fails if blob is marked read-only. */ 490 blob->md_ro = true; 491 rc = spdk_blob_resize(blob, 5); 492 CU_ASSERT(rc == -EPERM); 493 blob->md_ro = false; 494 495 /* The blob started at 0 clusters. Resize it to be 5. */ 496 rc = spdk_blob_resize(blob, 5); 497 CU_ASSERT(rc == 0); 498 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 499 500 /* Shrink the blob to 3 clusters. This will not actually release 501 * the old clusters until the blob is synced. 502 */ 503 rc = spdk_blob_resize(blob, 3); 504 CU_ASSERT(rc == 0); 505 /* Verify there are still 5 clusters in use */ 506 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 507 508 spdk_blob_sync_md(blob, blob_op_complete, NULL); 509 CU_ASSERT(g_bserrno == 0); 510 /* Now there are only 3 clusters in use */ 511 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 512 513 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 514 rc = spdk_blob_resize(blob, 10); 515 CU_ASSERT(rc == 0); 516 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 517 518 /* Try to resize the blob to size larger than blobstore. */ 519 rc = spdk_blob_resize(blob, bs->total_clusters + 1); 520 CU_ASSERT(rc == -ENOSPC); 521 522 spdk_blob_close(blob, blob_op_complete, NULL); 523 CU_ASSERT(g_bserrno == 0); 524 525 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 526 CU_ASSERT(g_bserrno == 0); 527 528 spdk_bs_unload(g_bs, bs_op_complete, NULL); 529 CU_ASSERT(g_bserrno == 0); 530 g_bs = NULL; 531 } 532 533 static void 534 blob_read_only(void) 535 { 536 struct spdk_blob_store *bs; 537 struct spdk_bs_dev *dev; 538 struct spdk_blob *blob; 539 struct spdk_bs_opts opts; 540 spdk_blob_id blobid; 541 int rc; 542 543 dev = init_dev(); 544 spdk_bs_opts_init(&opts); 545 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 546 547 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 548 CU_ASSERT(g_bserrno == 0); 549 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 550 bs = g_bs; 551 552 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 553 CU_ASSERT(g_bserrno == 0); 554 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 555 blobid = g_blobid; 556 557 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 558 CU_ASSERT(g_bserrno == 0); 559 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 560 blob = g_blob; 561 562 rc = spdk_blob_set_read_only(blob); 563 CU_ASSERT(rc == 0); 564 565 CU_ASSERT(blob->data_ro == false); 566 CU_ASSERT(blob->md_ro == false); 567 568 spdk_blob_sync_md(blob, bs_op_complete, NULL); 569 570 CU_ASSERT(blob->data_ro == true); 571 CU_ASSERT(blob->md_ro == true); 572 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 573 574 spdk_blob_close(blob, blob_op_complete, NULL); 575 CU_ASSERT(g_bserrno == 0); 576 577 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 578 CU_ASSERT(g_bserrno == 0); 579 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 580 blob = g_blob; 581 582 CU_ASSERT(blob->data_ro == true); 583 CU_ASSERT(blob->md_ro == true); 584 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 585 586 spdk_blob_close(blob, blob_op_complete, NULL); 587 CU_ASSERT(g_bserrno == 0); 588 589 spdk_bs_unload(g_bs, bs_op_complete, NULL); 590 CU_ASSERT(g_bserrno == 0); 591 g_bs = NULL; 592 g_blob = NULL; 593 g_blobid = 0; 594 595 /* Load an existing blob store */ 596 dev = init_dev(); 597 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 598 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 599 CU_ASSERT(g_bserrno == 0); 600 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 601 602 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 603 CU_ASSERT(g_bserrno == 0); 604 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 605 blob = g_blob; 606 607 CU_ASSERT(blob->data_ro == true); 608 CU_ASSERT(blob->md_ro == true); 609 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 610 611 spdk_blob_close(blob, blob_op_complete, NULL); 612 CU_ASSERT(g_bserrno == 0); 613 614 spdk_bs_unload(g_bs, bs_op_complete, NULL); 615 CU_ASSERT(g_bserrno == 0); 616 617 } 618 619 static void 620 channel_ops(void) 621 { 622 struct spdk_blob_store *bs; 623 struct spdk_bs_dev *dev; 624 struct spdk_io_channel *channel; 625 626 dev = init_dev(); 627 628 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 629 CU_ASSERT(g_bserrno == 0); 630 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 631 bs = g_bs; 632 633 channel = spdk_bs_alloc_io_channel(bs); 634 CU_ASSERT(channel != NULL); 635 636 spdk_bs_free_io_channel(channel); 637 638 spdk_bs_unload(g_bs, bs_op_complete, NULL); 639 CU_ASSERT(g_bserrno == 0); 640 g_bs = NULL; 641 } 642 643 static void 644 blob_write(void) 645 { 646 struct spdk_blob_store *bs; 647 struct spdk_bs_dev *dev; 648 struct spdk_blob *blob; 649 struct spdk_io_channel *channel; 650 spdk_blob_id blobid; 651 uint64_t pages_per_cluster; 652 uint8_t payload[10 * 4096]; 653 int rc; 654 655 dev = init_dev(); 656 657 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 658 CU_ASSERT(g_bserrno == 0); 659 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 660 bs = g_bs; 661 662 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 663 664 channel = spdk_bs_alloc_io_channel(bs); 665 CU_ASSERT(channel != NULL); 666 667 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 668 CU_ASSERT(g_bserrno == 0); 669 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 670 blobid = g_blobid; 671 672 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 673 CU_ASSERT(g_bserrno == 0); 674 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 675 blob = g_blob; 676 677 /* Write to a blob with 0 size */ 678 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 679 CU_ASSERT(g_bserrno == -EINVAL); 680 681 /* Resize the blob */ 682 rc = spdk_blob_resize(blob, 5); 683 CU_ASSERT(rc == 0); 684 685 /* Confirm that write fails if blob is marked read-only. */ 686 blob->data_ro = true; 687 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 688 CU_ASSERT(g_bserrno == -EPERM); 689 blob->data_ro = false; 690 691 /* Write to the blob */ 692 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 693 CU_ASSERT(g_bserrno == 0); 694 695 /* Write starting beyond the end */ 696 spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 697 NULL); 698 CU_ASSERT(g_bserrno == -EINVAL); 699 700 /* Write starting at a valid location but going off the end */ 701 spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 702 blob_op_complete, NULL); 703 CU_ASSERT(g_bserrno == -EINVAL); 704 705 spdk_blob_close(blob, blob_op_complete, NULL); 706 CU_ASSERT(g_bserrno == 0); 707 708 spdk_bs_free_io_channel(channel); 709 710 spdk_bs_unload(g_bs, bs_op_complete, NULL); 711 CU_ASSERT(g_bserrno == 0); 712 g_bs = NULL; 713 } 714 715 static void 716 blob_read(void) 717 { 718 struct spdk_blob_store *bs; 719 struct spdk_bs_dev *dev; 720 struct spdk_blob *blob; 721 struct spdk_io_channel *channel; 722 spdk_blob_id blobid; 723 uint64_t pages_per_cluster; 724 uint8_t payload[10 * 4096]; 725 int rc; 726 727 dev = init_dev(); 728 729 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 730 CU_ASSERT(g_bserrno == 0); 731 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 732 bs = g_bs; 733 734 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 735 736 channel = spdk_bs_alloc_io_channel(bs); 737 CU_ASSERT(channel != NULL); 738 739 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 740 CU_ASSERT(g_bserrno == 0); 741 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 742 blobid = g_blobid; 743 744 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 745 CU_ASSERT(g_bserrno == 0); 746 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 747 blob = g_blob; 748 749 /* Read from a blob with 0 size */ 750 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 751 CU_ASSERT(g_bserrno == -EINVAL); 752 753 /* Resize the blob */ 754 rc = spdk_blob_resize(blob, 5); 755 CU_ASSERT(rc == 0); 756 757 /* Confirm that read passes if blob is marked read-only. */ 758 blob->data_ro = true; 759 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 760 CU_ASSERT(g_bserrno == 0); 761 blob->data_ro = false; 762 763 /* Read from the blob */ 764 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 765 CU_ASSERT(g_bserrno == 0); 766 767 /* Read starting beyond the end */ 768 spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 769 NULL); 770 CU_ASSERT(g_bserrno == -EINVAL); 771 772 /* Read starting at a valid location but going off the end */ 773 spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 774 blob_op_complete, NULL); 775 CU_ASSERT(g_bserrno == -EINVAL); 776 777 spdk_blob_close(blob, blob_op_complete, NULL); 778 CU_ASSERT(g_bserrno == 0); 779 780 spdk_bs_free_io_channel(channel); 781 782 spdk_bs_unload(g_bs, bs_op_complete, NULL); 783 CU_ASSERT(g_bserrno == 0); 784 g_bs = NULL; 785 } 786 787 static void 788 blob_rw_verify(void) 789 { 790 struct spdk_blob_store *bs; 791 struct spdk_bs_dev *dev; 792 struct spdk_blob *blob; 793 struct spdk_io_channel *channel; 794 spdk_blob_id blobid; 795 uint8_t payload_read[10 * 4096]; 796 uint8_t payload_write[10 * 4096]; 797 int rc; 798 799 dev = init_dev(); 800 801 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 802 CU_ASSERT(g_bserrno == 0); 803 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 804 bs = g_bs; 805 806 channel = spdk_bs_alloc_io_channel(bs); 807 CU_ASSERT(channel != NULL); 808 809 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 810 CU_ASSERT(g_bserrno == 0); 811 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 812 blobid = g_blobid; 813 814 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 815 CU_ASSERT(g_bserrno == 0); 816 CU_ASSERT(g_blob != NULL); 817 blob = g_blob; 818 819 rc = spdk_blob_resize(blob, 32); 820 CU_ASSERT(rc == 0); 821 822 memset(payload_write, 0xE5, sizeof(payload_write)); 823 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 824 CU_ASSERT(g_bserrno == 0); 825 826 memset(payload_read, 0x00, sizeof(payload_read)); 827 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 828 CU_ASSERT(g_bserrno == 0); 829 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 830 831 spdk_blob_close(blob, blob_op_complete, NULL); 832 CU_ASSERT(g_bserrno == 0); 833 834 spdk_bs_free_io_channel(channel); 835 836 spdk_bs_unload(g_bs, bs_op_complete, NULL); 837 CU_ASSERT(g_bserrno == 0); 838 g_bs = NULL; 839 } 840 841 static void 842 blob_rw_verify_iov(void) 843 { 844 struct spdk_blob_store *bs; 845 struct spdk_bs_dev *dev; 846 struct spdk_blob *blob; 847 struct spdk_io_channel *channel; 848 spdk_blob_id blobid; 849 uint8_t payload_read[10 * 4096]; 850 uint8_t payload_write[10 * 4096]; 851 struct iovec iov_read[3]; 852 struct iovec iov_write[3]; 853 void *buf; 854 int rc; 855 856 dev = init_dev(); 857 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 858 859 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 860 CU_ASSERT(g_bserrno == 0); 861 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 862 bs = g_bs; 863 864 channel = spdk_bs_alloc_io_channel(bs); 865 CU_ASSERT(channel != NULL); 866 867 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 868 CU_ASSERT(g_bserrno == 0); 869 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 870 blobid = g_blobid; 871 872 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 873 CU_ASSERT(g_bserrno == 0); 874 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 875 blob = g_blob; 876 877 rc = spdk_blob_resize(blob, 2); 878 CU_ASSERT(rc == 0); 879 880 /* 881 * Manually adjust the offset of the blob's second cluster. This allows 882 * us to make sure that the readv/write code correctly accounts for I/O 883 * that cross cluster boundaries. Start by asserting that the allocated 884 * clusters are where we expect before modifying the second cluster. 885 */ 886 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 887 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 888 blob->active.clusters[1] = 3 * 256; 889 890 memset(payload_write, 0xE5, sizeof(payload_write)); 891 iov_write[0].iov_base = payload_write; 892 iov_write[0].iov_len = 1 * 4096; 893 iov_write[1].iov_base = payload_write + 1 * 4096; 894 iov_write[1].iov_len = 5 * 4096; 895 iov_write[2].iov_base = payload_write + 6 * 4096; 896 iov_write[2].iov_len = 4 * 4096; 897 /* 898 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 899 * will get written to the first cluster, the last 4 to the second cluster. 900 */ 901 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 902 CU_ASSERT(g_bserrno == 0); 903 904 memset(payload_read, 0xAA, sizeof(payload_read)); 905 iov_read[0].iov_base = payload_read; 906 iov_read[0].iov_len = 3 * 4096; 907 iov_read[1].iov_base = payload_read + 3 * 4096; 908 iov_read[1].iov_len = 4 * 4096; 909 iov_read[2].iov_base = payload_read + 7 * 4096; 910 iov_read[2].iov_len = 3 * 4096; 911 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 912 CU_ASSERT(g_bserrno == 0); 913 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 914 915 buf = calloc(1, 256 * 4096); 916 SPDK_CU_ASSERT_FATAL(buf != NULL); 917 /* Check that cluster 2 on "disk" was not modified. */ 918 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 919 free(buf); 920 921 spdk_blob_close(blob, blob_op_complete, NULL); 922 CU_ASSERT(g_bserrno == 0); 923 924 spdk_bs_free_io_channel(channel); 925 926 spdk_bs_unload(g_bs, bs_op_complete, NULL); 927 CU_ASSERT(g_bserrno == 0); 928 g_bs = NULL; 929 } 930 931 static uint32_t 932 bs_channel_get_req_count(struct spdk_io_channel *_channel) 933 { 934 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 935 struct spdk_bs_request_set *set; 936 uint32_t count = 0; 937 938 TAILQ_FOREACH(set, &channel->reqs, link) { 939 count++; 940 } 941 942 return count; 943 } 944 945 static void 946 blob_rw_verify_iov_nomem(void) 947 { 948 struct spdk_blob_store *bs; 949 struct spdk_bs_dev *dev; 950 struct spdk_blob *blob; 951 struct spdk_io_channel *channel; 952 spdk_blob_id blobid; 953 uint8_t payload_write[10 * 4096]; 954 struct iovec iov_write[3]; 955 uint32_t req_count; 956 int rc; 957 958 dev = init_dev(); 959 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 960 961 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 962 CU_ASSERT(g_bserrno == 0); 963 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 964 bs = g_bs; 965 966 channel = spdk_bs_alloc_io_channel(bs); 967 CU_ASSERT(channel != NULL); 968 969 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 970 CU_ASSERT(g_bserrno == 0); 971 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 972 blobid = g_blobid; 973 974 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 975 CU_ASSERT(g_bserrno == 0); 976 CU_ASSERT(g_blob != NULL); 977 blob = g_blob; 978 979 rc = spdk_blob_resize(blob, 2); 980 CU_ASSERT(rc == 0); 981 982 /* 983 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 984 * will get written to the first cluster, the last 4 to the second cluster. 985 */ 986 iov_write[0].iov_base = payload_write; 987 iov_write[0].iov_len = 1 * 4096; 988 iov_write[1].iov_base = payload_write + 1 * 4096; 989 iov_write[1].iov_len = 5 * 4096; 990 iov_write[2].iov_base = payload_write + 6 * 4096; 991 iov_write[2].iov_len = 4 * 4096; 992 MOCK_SET(calloc, void *, NULL); 993 req_count = bs_channel_get_req_count(channel); 994 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 995 CU_ASSERT(g_bserrno = -ENOMEM); 996 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 997 MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU); 998 999 spdk_blob_close(blob, blob_op_complete, NULL); 1000 CU_ASSERT(g_bserrno == 0); 1001 1002 spdk_bs_free_io_channel(channel); 1003 1004 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1005 CU_ASSERT(g_bserrno == 0); 1006 g_bs = NULL; 1007 } 1008 1009 static void 1010 blob_rw_iov_read_only(void) 1011 { 1012 struct spdk_blob_store *bs; 1013 struct spdk_bs_dev *dev; 1014 struct spdk_blob *blob; 1015 struct spdk_io_channel *channel; 1016 spdk_blob_id blobid; 1017 uint8_t payload_read[4096]; 1018 uint8_t payload_write[4096]; 1019 struct iovec iov_read; 1020 struct iovec iov_write; 1021 int rc; 1022 1023 dev = init_dev(); 1024 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1025 1026 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1027 CU_ASSERT(g_bserrno == 0); 1028 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1029 bs = g_bs; 1030 1031 channel = spdk_bs_alloc_io_channel(bs); 1032 CU_ASSERT(channel != NULL); 1033 1034 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1035 CU_ASSERT(g_bserrno == 0); 1036 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1037 blobid = g_blobid; 1038 1039 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1040 CU_ASSERT(g_bserrno == 0); 1041 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1042 blob = g_blob; 1043 1044 rc = spdk_blob_resize(blob, 2); 1045 CU_ASSERT(rc == 0); 1046 1047 /* Verify that writev failed if read_only flag is set. */ 1048 blob->data_ro = true; 1049 iov_write.iov_base = payload_write; 1050 iov_write.iov_len = sizeof(payload_write); 1051 spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL); 1052 CU_ASSERT(g_bserrno == -EPERM); 1053 1054 /* Verify that reads pass if data_ro flag is set. */ 1055 iov_read.iov_base = payload_read; 1056 iov_read.iov_len = sizeof(payload_read); 1057 spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL); 1058 CU_ASSERT(g_bserrno == 0); 1059 1060 spdk_blob_close(blob, blob_op_complete, NULL); 1061 CU_ASSERT(g_bserrno == 0); 1062 1063 spdk_bs_free_io_channel(channel); 1064 1065 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1066 CU_ASSERT(g_bserrno == 0); 1067 g_bs = NULL; 1068 } 1069 1070 static void 1071 blob_unmap(void) 1072 { 1073 struct spdk_blob_store *bs; 1074 struct spdk_bs_dev *dev; 1075 struct spdk_blob *blob; 1076 struct spdk_io_channel *channel; 1077 spdk_blob_id blobid; 1078 struct spdk_blob_opts opts; 1079 uint8_t payload[4096]; 1080 int rc; 1081 int i; 1082 1083 dev = init_dev(); 1084 1085 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1086 CU_ASSERT(g_bserrno == 0); 1087 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1088 bs = g_bs; 1089 1090 channel = spdk_bs_alloc_io_channel(bs); 1091 CU_ASSERT(channel != NULL); 1092 1093 spdk_blob_opts_init(&opts); 1094 opts.num_clusters = 10; 1095 1096 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1097 CU_ASSERT(g_bserrno == 0); 1098 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1099 blobid = g_blobid; 1100 1101 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1102 CU_ASSERT(g_bserrno == 0); 1103 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1104 blob = g_blob; 1105 1106 rc = spdk_blob_resize(blob, 10); 1107 CU_ASSERT(rc == 0); 1108 1109 memset(payload, 0, sizeof(payload)); 1110 payload[0] = 0xFF; 1111 1112 /* 1113 * Set first byte of every cluster to 0xFF. 1114 * First cluster on device is reserved so let's start from cluster number 1 1115 */ 1116 for (i = 1; i < 11; i++) { 1117 g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF; 1118 } 1119 1120 /* Confirm writes */ 1121 for (i = 0; i < 10; i++) { 1122 payload[0] = 0; 1123 spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1, 1124 blob_op_complete, NULL); 1125 CU_ASSERT(g_bserrno == 0); 1126 CU_ASSERT(payload[0] == 0xFF); 1127 } 1128 1129 /* Mark some clusters as unallocated */ 1130 blob->active.clusters[1] = 0; 1131 blob->active.clusters[2] = 0; 1132 blob->active.clusters[3] = 0; 1133 blob->active.clusters[6] = 0; 1134 blob->active.clusters[8] = 0; 1135 1136 /* Unmap clusters by resizing to 0 */ 1137 rc = spdk_blob_resize(blob, 0); 1138 CU_ASSERT(rc == 0); 1139 1140 spdk_blob_sync_md(blob, blob_op_complete, NULL); 1141 CU_ASSERT(g_bserrno == 0); 1142 1143 /* Confirm that only 'allocated' clusters were unmaped */ 1144 for (i = 1; i < 11; i++) { 1145 switch (i) { 1146 case 2: 1147 case 3: 1148 case 4: 1149 case 7: 1150 case 9: 1151 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF); 1152 break; 1153 default: 1154 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0); 1155 break; 1156 } 1157 } 1158 1159 spdk_blob_close(blob, blob_op_complete, NULL); 1160 CU_ASSERT(g_bserrno == 0); 1161 1162 spdk_bs_free_io_channel(channel); 1163 1164 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1165 CU_ASSERT(g_bserrno == 0); 1166 g_bs = NULL; 1167 } 1168 1169 1170 static void 1171 blob_iter(void) 1172 { 1173 struct spdk_blob_store *bs; 1174 struct spdk_bs_dev *dev; 1175 struct spdk_blob *blob; 1176 spdk_blob_id blobid; 1177 1178 dev = init_dev(); 1179 1180 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1181 CU_ASSERT(g_bserrno == 0); 1182 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1183 bs = g_bs; 1184 1185 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1186 CU_ASSERT(g_blob == NULL); 1187 CU_ASSERT(g_bserrno == -ENOENT); 1188 1189 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1190 CU_ASSERT(g_bserrno == 0); 1191 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1192 blobid = g_blobid; 1193 1194 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1195 CU_ASSERT(g_blob != NULL); 1196 CU_ASSERT(g_bserrno == 0); 1197 blob = g_blob; 1198 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 1199 1200 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 1201 CU_ASSERT(g_blob == NULL); 1202 CU_ASSERT(g_bserrno == -ENOENT); 1203 1204 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1205 CU_ASSERT(g_bserrno == 0); 1206 g_bs = NULL; 1207 } 1208 1209 static void 1210 blob_xattr(void) 1211 { 1212 struct spdk_blob_store *bs; 1213 struct spdk_bs_dev *dev; 1214 struct spdk_blob *blob; 1215 spdk_blob_id blobid; 1216 uint64_t length; 1217 int rc; 1218 const char *name1, *name2; 1219 const void *value; 1220 size_t value_len; 1221 struct spdk_xattr_names *names; 1222 1223 dev = init_dev(); 1224 1225 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1226 CU_ASSERT(g_bserrno == 0); 1227 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1228 bs = g_bs; 1229 1230 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1231 CU_ASSERT(g_bserrno == 0); 1232 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1233 blobid = g_blobid; 1234 1235 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1236 CU_ASSERT(g_bserrno == 0); 1237 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1238 blob = g_blob; 1239 1240 /* Test that set_xattr fails if md_ro flag is set. */ 1241 blob->md_ro = true; 1242 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1243 CU_ASSERT(rc == -EPERM); 1244 1245 blob->md_ro = false; 1246 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1247 CU_ASSERT(rc == 0); 1248 1249 length = 2345; 1250 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1251 CU_ASSERT(rc == 0); 1252 1253 /* Overwrite "length" xattr. */ 1254 length = 3456; 1255 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1256 CU_ASSERT(rc == 0); 1257 1258 /* get_xattr should still work even if md_ro flag is set. */ 1259 value = NULL; 1260 blob->md_ro = true; 1261 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1262 CU_ASSERT(rc == 0); 1263 SPDK_CU_ASSERT_FATAL(value != NULL); 1264 CU_ASSERT(*(uint64_t *)value == length); 1265 CU_ASSERT(value_len == 8); 1266 blob->md_ro = false; 1267 1268 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1269 CU_ASSERT(rc == -ENOENT); 1270 1271 names = NULL; 1272 rc = spdk_blob_get_xattr_names(blob, &names); 1273 CU_ASSERT(rc == 0); 1274 SPDK_CU_ASSERT_FATAL(names != NULL); 1275 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 1276 name1 = spdk_xattr_names_get_name(names, 0); 1277 SPDK_CU_ASSERT_FATAL(name1 != NULL); 1278 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 1279 name2 = spdk_xattr_names_get_name(names, 1); 1280 SPDK_CU_ASSERT_FATAL(name2 != NULL); 1281 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 1282 CU_ASSERT(strcmp(name1, name2)); 1283 spdk_xattr_names_free(names); 1284 1285 /* Confirm that remove_xattr fails if md_ro is set to true. */ 1286 blob->md_ro = true; 1287 rc = spdk_blob_remove_xattr(blob, "name"); 1288 CU_ASSERT(rc == -EPERM); 1289 1290 blob->md_ro = false; 1291 rc = spdk_blob_remove_xattr(blob, "name"); 1292 CU_ASSERT(rc == 0); 1293 1294 rc = spdk_blob_remove_xattr(blob, "foobar"); 1295 CU_ASSERT(rc == -ENOENT); 1296 1297 /* Set internal xattr */ 1298 length = 7898; 1299 rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true); 1300 CU_ASSERT(rc == 0); 1301 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 1302 CU_ASSERT(rc == 0); 1303 CU_ASSERT(*(uint64_t *)value == length); 1304 /* try to get public xattr with same name */ 1305 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 1306 CU_ASSERT(rc != 0); 1307 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false); 1308 CU_ASSERT(rc != 0); 1309 /* Check if SPDK_BLOB_INTERNAL_XATTR is set */ 1310 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 1311 SPDK_BLOB_INTERNAL_XATTR) 1312 1313 spdk_blob_close(blob, blob_op_complete, NULL); 1314 1315 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1316 1317 /* Check if xattrs are persisted */ 1318 dev = init_dev(); 1319 1320 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 1321 CU_ASSERT(g_bserrno == 0); 1322 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1323 1324 bs = g_bs; 1325 1326 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1327 CU_ASSERT(g_bserrno == 0); 1328 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1329 blob = g_blob; 1330 1331 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 1332 CU_ASSERT(rc == 0); 1333 CU_ASSERT(*(uint64_t *)value == length); 1334 1335 /* try to get internal xattr trough public call */ 1336 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 1337 CU_ASSERT(rc != 0); 1338 1339 rc = _spdk_blob_remove_xattr(blob, "internal", true); 1340 CU_ASSERT(rc == 0); 1341 1342 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0); 1343 1344 CU_ASSERT(g_bserrno == 0); 1345 g_bs = NULL; 1346 } 1347 1348 static void 1349 bs_load(void) 1350 { 1351 struct spdk_bs_dev *dev; 1352 spdk_blob_id blobid; 1353 struct spdk_blob *blob; 1354 struct spdk_bs_super_block *super_block; 1355 uint64_t length; 1356 int rc; 1357 const void *value; 1358 size_t value_len; 1359 struct spdk_bs_opts opts; 1360 1361 dev = init_dev(); 1362 spdk_bs_opts_init(&opts); 1363 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1364 1365 /* Initialize a new blob store */ 1366 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1367 CU_ASSERT(g_bserrno == 0); 1368 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1369 1370 /* Try to open a blobid that does not exist */ 1371 spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 1372 CU_ASSERT(g_bserrno == -ENOENT); 1373 CU_ASSERT(g_blob == NULL); 1374 1375 /* Create a blob */ 1376 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1377 CU_ASSERT(g_bserrno == 0); 1378 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1379 blobid = g_blobid; 1380 1381 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1382 CU_ASSERT(g_bserrno == 0); 1383 CU_ASSERT(g_blob != NULL); 1384 blob = g_blob; 1385 1386 /* Try again to open valid blob but without the upper bit set */ 1387 spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 1388 CU_ASSERT(g_bserrno == -ENOENT); 1389 CU_ASSERT(g_blob == NULL); 1390 1391 /* Set some xattrs */ 1392 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1393 CU_ASSERT(rc == 0); 1394 1395 length = 2345; 1396 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1397 CU_ASSERT(rc == 0); 1398 1399 /* Resize the blob */ 1400 rc = spdk_blob_resize(blob, 10); 1401 CU_ASSERT(rc == 0); 1402 1403 spdk_blob_close(blob, blob_op_complete, NULL); 1404 CU_ASSERT(g_bserrno == 0); 1405 blob = NULL; 1406 g_blob = NULL; 1407 g_blobid = SPDK_BLOBID_INVALID; 1408 1409 /* Unload the blob store */ 1410 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1411 CU_ASSERT(g_bserrno == 0); 1412 g_bs = NULL; 1413 g_blob = NULL; 1414 g_blobid = 0; 1415 1416 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1417 CU_ASSERT(super_block->clean == 1); 1418 1419 1420 /* Load an existing blob store */ 1421 dev = init_dev(); 1422 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1423 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1424 CU_ASSERT(g_bserrno == 0); 1425 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1426 1427 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1428 CU_ASSERT(super_block->clean == 0); 1429 1430 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1431 CU_ASSERT(g_bserrno == 0); 1432 CU_ASSERT(g_blob != NULL); 1433 blob = g_blob; 1434 1435 /* Get the xattrs */ 1436 value = NULL; 1437 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1438 CU_ASSERT(rc == 0); 1439 SPDK_CU_ASSERT_FATAL(value != NULL); 1440 CU_ASSERT(*(uint64_t *)value == length); 1441 CU_ASSERT(value_len == 8); 1442 1443 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1444 CU_ASSERT(rc == -ENOENT); 1445 1446 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1447 1448 spdk_blob_close(blob, blob_op_complete, NULL); 1449 CU_ASSERT(g_bserrno == 0); 1450 blob = NULL; 1451 g_blob = NULL; 1452 g_blobid = SPDK_BLOBID_INVALID; 1453 1454 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1455 CU_ASSERT(g_bserrno == 0); 1456 g_bs = NULL; 1457 } 1458 1459 static void 1460 bs_type(void) 1461 { 1462 struct spdk_bs_dev *dev; 1463 struct spdk_bs_opts opts; 1464 1465 dev = init_dev(); 1466 spdk_bs_opts_init(&opts); 1467 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1468 1469 /* Initialize a new blob store */ 1470 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1471 CU_ASSERT(g_bserrno == 0); 1472 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1473 1474 /* Unload the blob store */ 1475 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1476 CU_ASSERT(g_bserrno == 0); 1477 g_bs = NULL; 1478 g_blob = NULL; 1479 g_blobid = 0; 1480 1481 /* Load non existing blobstore type */ 1482 dev = init_dev(); 1483 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1484 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1485 CU_ASSERT(g_bserrno != 0); 1486 1487 /* Load with empty blobstore type */ 1488 dev = init_dev(); 1489 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1490 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1491 CU_ASSERT(g_bserrno == 0); 1492 1493 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1494 CU_ASSERT(g_bserrno == 0); 1495 g_bs = NULL; 1496 1497 /* Initialize a new blob store with empty bstype */ 1498 dev = init_dev(); 1499 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1500 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1501 CU_ASSERT(g_bserrno == 0); 1502 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1503 1504 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1505 CU_ASSERT(g_bserrno == 0); 1506 g_bs = NULL; 1507 1508 /* Load non existing blobstore type */ 1509 dev = init_dev(); 1510 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1511 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1512 CU_ASSERT(g_bserrno != 0); 1513 1514 /* Load with empty blobstore type */ 1515 dev = init_dev(); 1516 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1517 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1518 CU_ASSERT(g_bserrno == 0); 1519 1520 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1521 CU_ASSERT(g_bserrno == 0); 1522 g_bs = NULL; 1523 } 1524 1525 static void 1526 bs_super_block(void) 1527 { 1528 struct spdk_bs_dev *dev; 1529 struct spdk_bs_super_block *super_block; 1530 struct spdk_bs_opts opts; 1531 struct spdk_bs_super_block_ver1 super_block_v1; 1532 1533 dev = init_dev(); 1534 spdk_bs_opts_init(&opts); 1535 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1536 1537 /* Initialize a new blob store */ 1538 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1539 CU_ASSERT(g_bserrno == 0); 1540 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1541 1542 /* Unload the blob store */ 1543 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1544 CU_ASSERT(g_bserrno == 0); 1545 g_bs = NULL; 1546 g_blob = NULL; 1547 g_blobid = 0; 1548 1549 /* Load an existing blob store with version newer than supported */ 1550 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1551 super_block->version++; 1552 1553 dev = init_dev(); 1554 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1555 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1556 CU_ASSERT(g_bserrno != 0); 1557 1558 /* Create a new blob store with super block version 1 */ 1559 dev = init_dev(); 1560 super_block_v1.version = 1; 1561 strncpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 1562 super_block_v1.length = 0x1000; 1563 super_block_v1.clean = 1; 1564 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 1565 super_block_v1.cluster_size = 0x100000; 1566 super_block_v1.used_page_mask_start = 0x01; 1567 super_block_v1.used_page_mask_len = 0x01; 1568 super_block_v1.used_cluster_mask_start = 0x02; 1569 super_block_v1.used_cluster_mask_len = 0x01; 1570 super_block_v1.md_start = 0x03; 1571 super_block_v1.md_len = 0x40; 1572 memset(super_block_v1.reserved, 0, 4036); 1573 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 1574 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 1575 1576 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1577 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1578 CU_ASSERT(g_bserrno == 0); 1579 1580 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1581 CU_ASSERT(g_bserrno == 0); 1582 g_bs = NULL; 1583 } 1584 1585 /* 1586 * Create a blobstore and then unload it. 1587 */ 1588 static void 1589 bs_unload(void) 1590 { 1591 struct spdk_bs_dev *dev; 1592 struct spdk_blob_store *bs; 1593 spdk_blob_id blobid; 1594 struct spdk_blob *blob; 1595 1596 dev = init_dev(); 1597 1598 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1599 CU_ASSERT(g_bserrno == 0); 1600 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1601 bs = g_bs; 1602 1603 /* Create a blob and open it. */ 1604 g_bserrno = -1; 1605 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1606 CU_ASSERT(g_bserrno == 0); 1607 CU_ASSERT(g_blobid > 0); 1608 blobid = g_blobid; 1609 1610 g_bserrno = -1; 1611 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1612 CU_ASSERT(g_bserrno == 0); 1613 CU_ASSERT(g_blob != NULL); 1614 blob = g_blob; 1615 1616 /* Try to unload blobstore, should fail with open blob */ 1617 g_bserrno = -1; 1618 spdk_bs_unload(bs, bs_op_complete, NULL); 1619 CU_ASSERT(g_bserrno == -EBUSY); 1620 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1621 1622 /* Close the blob, then successfully unload blobstore */ 1623 g_bserrno = -1; 1624 spdk_blob_close(blob, blob_op_complete, NULL); 1625 CU_ASSERT(g_bserrno == 0); 1626 1627 g_bserrno = -1; 1628 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1629 CU_ASSERT(g_bserrno == 0); 1630 g_bs = NULL; 1631 } 1632 1633 /* 1634 * Create a blobstore with a cluster size different than the default, and ensure it is 1635 * persisted. 1636 */ 1637 static void 1638 bs_cluster_sz(void) 1639 { 1640 struct spdk_bs_dev *dev; 1641 struct spdk_bs_opts opts; 1642 uint32_t cluster_sz; 1643 1644 /* Set cluster size to zero */ 1645 dev = init_dev(); 1646 spdk_bs_opts_init(&opts); 1647 opts.cluster_sz = 0; 1648 1649 /* Initialize a new blob store */ 1650 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1651 CU_ASSERT(g_bserrno == -EINVAL); 1652 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1653 1654 /* 1655 * Set cluster size to blobstore page size, 1656 * to work it is required to be at least twice the blobstore page size. 1657 */ 1658 dev = init_dev(); 1659 spdk_bs_opts_init(&opts); 1660 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 1661 1662 /* Initialize a new blob store */ 1663 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1664 CU_ASSERT(g_bserrno == -ENOMEM); 1665 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1666 1667 /* 1668 * Set cluster size to lower than page size, 1669 * to work it is required to be at least twice the blobstore page size. 1670 */ 1671 dev = init_dev(); 1672 spdk_bs_opts_init(&opts); 1673 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 1674 1675 /* Initialize a new blob store */ 1676 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1677 CU_ASSERT(g_bserrno == -ENOMEM); 1678 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1679 1680 /* Set cluster size to twice the default */ 1681 dev = init_dev(); 1682 spdk_bs_opts_init(&opts); 1683 opts.cluster_sz *= 2; 1684 cluster_sz = opts.cluster_sz; 1685 1686 /* Initialize a new blob store */ 1687 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1688 CU_ASSERT(g_bserrno == 0); 1689 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1690 1691 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1692 1693 /* Unload the blob store */ 1694 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1695 CU_ASSERT(g_bserrno == 0); 1696 g_bs = NULL; 1697 g_blob = NULL; 1698 g_blobid = 0; 1699 1700 dev = init_dev(); 1701 /* Load an existing blob store */ 1702 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1703 CU_ASSERT(g_bserrno == 0); 1704 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1705 1706 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1707 1708 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1709 CU_ASSERT(g_bserrno == 0); 1710 g_bs = NULL; 1711 } 1712 1713 /* 1714 * Create a blobstore, reload it and ensure total usable cluster count 1715 * stays the same. 1716 */ 1717 static void 1718 bs_usable_clusters(void) 1719 { 1720 struct spdk_bs_dev *dev; 1721 struct spdk_bs_opts opts; 1722 uint32_t clusters; 1723 int i, rc; 1724 1725 /* Init blobstore */ 1726 dev = init_dev(); 1727 spdk_bs_opts_init(&opts); 1728 1729 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1730 CU_ASSERT(g_bserrno == 0); 1731 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1732 1733 clusters = spdk_bs_total_data_cluster_count(g_bs); 1734 1735 /* Unload the blob store */ 1736 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1737 CU_ASSERT(g_bserrno == 0); 1738 g_bs = NULL; 1739 1740 dev = init_dev(); 1741 /* Load an existing blob store */ 1742 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1743 CU_ASSERT(g_bserrno == 0); 1744 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1745 1746 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1747 1748 /* Create and resize blobs to make sure that useable cluster count won't change */ 1749 for (i = 0; i < 4; i++) { 1750 g_bserrno = -1; 1751 g_blobid = SPDK_BLOBID_INVALID; 1752 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1753 CU_ASSERT(g_bserrno == 0); 1754 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1755 1756 g_bserrno = -1; 1757 g_blob = NULL; 1758 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 1759 CU_ASSERT(g_bserrno == 0); 1760 CU_ASSERT(g_blob != NULL); 1761 1762 rc = spdk_blob_resize(g_blob, 10); 1763 CU_ASSERT(rc == 0); 1764 1765 g_bserrno = -1; 1766 spdk_blob_close(g_blob, blob_op_complete, NULL); 1767 CU_ASSERT(g_bserrno == 0); 1768 1769 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1770 } 1771 1772 /* Reload the blob store to make sure that nothing changed */ 1773 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1774 CU_ASSERT(g_bserrno == 0); 1775 g_bs = NULL; 1776 1777 dev = init_dev(); 1778 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1779 CU_ASSERT(g_bserrno == 0); 1780 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1781 1782 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1783 1784 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1785 CU_ASSERT(g_bserrno == 0); 1786 g_bs = NULL; 1787 } 1788 1789 /* 1790 * Test resizing of the metadata blob. This requires creating enough blobs 1791 * so that one cluster is not enough to fit the metadata for those blobs. 1792 * To induce this condition to happen more quickly, we reduce the cluster 1793 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 1794 */ 1795 static void 1796 bs_resize_md(void) 1797 { 1798 const int CLUSTER_PAGE_COUNT = 4; 1799 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 1800 struct spdk_bs_dev *dev; 1801 struct spdk_bs_opts opts; 1802 uint32_t cluster_sz; 1803 spdk_blob_id blobids[NUM_BLOBS]; 1804 int i; 1805 1806 1807 dev = init_dev(); 1808 spdk_bs_opts_init(&opts); 1809 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 1810 cluster_sz = opts.cluster_sz; 1811 1812 /* Initialize a new blob store */ 1813 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1814 CU_ASSERT(g_bserrno == 0); 1815 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1816 1817 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1818 1819 for (i = 0; i < NUM_BLOBS; i++) { 1820 g_bserrno = -1; 1821 g_blobid = SPDK_BLOBID_INVALID; 1822 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1823 CU_ASSERT(g_bserrno == 0); 1824 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1825 blobids[i] = g_blobid; 1826 } 1827 1828 /* Unload the blob store */ 1829 g_bserrno = -1; 1830 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1831 CU_ASSERT(g_bserrno == 0); 1832 1833 /* Load an existing blob store */ 1834 g_bserrno = -1; 1835 g_bs = NULL; 1836 dev = init_dev(); 1837 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1838 CU_ASSERT(g_bserrno == 0); 1839 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1840 1841 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1842 1843 for (i = 0; i < NUM_BLOBS; i++) { 1844 g_bserrno = -1; 1845 g_blob = NULL; 1846 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 1847 CU_ASSERT(g_bserrno == 0); 1848 CU_ASSERT(g_blob != NULL); 1849 g_bserrno = -1; 1850 spdk_blob_close(g_blob, blob_op_complete, NULL); 1851 CU_ASSERT(g_bserrno == 0); 1852 } 1853 1854 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1855 CU_ASSERT(g_bserrno == 0); 1856 g_bs = NULL; 1857 } 1858 1859 static void 1860 bs_destroy(void) 1861 { 1862 struct spdk_bs_dev *dev; 1863 struct spdk_bs_opts opts; 1864 1865 /* Initialize a new blob store */ 1866 dev = init_dev(); 1867 spdk_bs_opts_init(&opts); 1868 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1869 CU_ASSERT(g_bserrno == 0); 1870 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1871 1872 /* Destroy the blob store */ 1873 g_bserrno = -1; 1874 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 1875 CU_ASSERT(g_bserrno == 0); 1876 1877 /* Loading an non-existent blob store should fail. */ 1878 g_bs = NULL; 1879 dev = init_dev(); 1880 1881 g_bserrno = 0; 1882 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1883 CU_ASSERT(g_bserrno != 0); 1884 } 1885 1886 /* Try to hit all of the corner cases associated with serializing 1887 * a blob to disk 1888 */ 1889 static void 1890 blob_serialize(void) 1891 { 1892 struct spdk_bs_dev *dev; 1893 struct spdk_bs_opts opts; 1894 struct spdk_blob_store *bs; 1895 spdk_blob_id blobid[2]; 1896 struct spdk_blob *blob[2]; 1897 uint64_t i; 1898 char *value; 1899 int rc; 1900 1901 dev = init_dev(); 1902 1903 /* Initialize a new blobstore with very small clusters */ 1904 spdk_bs_opts_init(&opts); 1905 opts.cluster_sz = dev->blocklen * 8; 1906 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1907 CU_ASSERT(g_bserrno == 0); 1908 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1909 bs = g_bs; 1910 1911 /* Create and open two blobs */ 1912 for (i = 0; i < 2; i++) { 1913 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1914 CU_ASSERT(g_bserrno == 0); 1915 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1916 blobid[i] = g_blobid; 1917 1918 /* Open a blob */ 1919 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1920 CU_ASSERT(g_bserrno == 0); 1921 CU_ASSERT(g_blob != NULL); 1922 blob[i] = g_blob; 1923 1924 /* Set a fairly large xattr on both blobs to eat up 1925 * metadata space 1926 */ 1927 value = calloc(dev->blocklen - 64, sizeof(char)); 1928 SPDK_CU_ASSERT_FATAL(value != NULL); 1929 memset(value, i, dev->blocklen / 2); 1930 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 1931 CU_ASSERT(rc == 0); 1932 free(value); 1933 } 1934 1935 /* Resize the blobs, alternating 1 cluster at a time. 1936 * This thwarts run length encoding and will cause spill 1937 * over of the extents. 1938 */ 1939 for (i = 0; i < 6; i++) { 1940 rc = spdk_blob_resize(blob[i % 2], (i / 2) + 1); 1941 CU_ASSERT(rc == 0); 1942 } 1943 1944 for (i = 0; i < 2; i++) { 1945 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 1946 CU_ASSERT(g_bserrno == 0); 1947 } 1948 1949 /* Close the blobs */ 1950 for (i = 0; i < 2; i++) { 1951 spdk_blob_close(blob[i], blob_op_complete, NULL); 1952 CU_ASSERT(g_bserrno == 0); 1953 } 1954 1955 /* Unload the blobstore */ 1956 spdk_bs_unload(bs, bs_op_complete, NULL); 1957 CU_ASSERT(g_bserrno == 0); 1958 g_bs = NULL; 1959 g_blob = NULL; 1960 g_blobid = 0; 1961 bs = NULL; 1962 1963 dev = init_dev(); 1964 /* Load an existing blob store */ 1965 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1966 CU_ASSERT(g_bserrno == 0); 1967 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1968 bs = g_bs; 1969 1970 for (i = 0; i < 2; i++) { 1971 blob[i] = NULL; 1972 1973 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1974 CU_ASSERT(g_bserrno == 0); 1975 CU_ASSERT(g_blob != NULL); 1976 blob[i] = g_blob; 1977 1978 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 1979 1980 spdk_blob_close(blob[i], blob_op_complete, NULL); 1981 CU_ASSERT(g_bserrno == 0); 1982 } 1983 1984 spdk_bs_unload(bs, bs_op_complete, NULL); 1985 CU_ASSERT(g_bserrno == 0); 1986 g_bs = NULL; 1987 } 1988 1989 static void 1990 blob_crc(void) 1991 { 1992 struct spdk_blob_store *bs; 1993 struct spdk_bs_dev *dev; 1994 struct spdk_blob *blob; 1995 spdk_blob_id blobid; 1996 uint32_t page_num; 1997 int index; 1998 struct spdk_blob_md_page *page; 1999 2000 dev = init_dev(); 2001 2002 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2003 CU_ASSERT(g_bserrno == 0); 2004 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2005 bs = g_bs; 2006 2007 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2008 CU_ASSERT(g_bserrno == 0); 2009 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2010 blobid = g_blobid; 2011 2012 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2013 CU_ASSERT(g_bserrno == 0); 2014 CU_ASSERT(g_blob != NULL); 2015 blob = g_blob; 2016 2017 spdk_blob_close(blob, blob_op_complete, NULL); 2018 CU_ASSERT(g_bserrno == 0); 2019 2020 page_num = _spdk_bs_blobid_to_page(blobid); 2021 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 2022 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2023 page->crc = 0; 2024 2025 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2026 CU_ASSERT(g_bserrno == -EINVAL); 2027 CU_ASSERT(g_blob == NULL); 2028 g_bserrno = 0; 2029 2030 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2031 CU_ASSERT(g_bserrno == -EINVAL); 2032 2033 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2034 CU_ASSERT(g_bserrno == 0); 2035 g_bs = NULL; 2036 } 2037 2038 static void 2039 super_block_crc(void) 2040 { 2041 struct spdk_bs_dev *dev; 2042 struct spdk_bs_super_block *super_block; 2043 struct spdk_bs_opts opts; 2044 2045 dev = init_dev(); 2046 spdk_bs_opts_init(&opts); 2047 2048 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2049 CU_ASSERT(g_bserrno == 0); 2050 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2051 2052 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2053 CU_ASSERT(g_bserrno == 0); 2054 g_bs = NULL; 2055 2056 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2057 super_block->crc = 0; 2058 dev = init_dev(); 2059 2060 /* Load an existing blob store */ 2061 g_bserrno = 0; 2062 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2063 CU_ASSERT(g_bserrno == -EILSEQ); 2064 } 2065 2066 /* For blob dirty shutdown test case we do the following sub-test cases: 2067 * 1 Initialize new blob store and create 1 blob with some xattrs, then we 2068 * dirty shutdown and reload the blob store and verify the xattrs. 2069 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 2070 * reload the blob store and verify the clusters number. 2071 * 3 Create the second blob and then dirty shutdown, reload the blob store 2072 * and verify the second blob. 2073 * 4 Delete the second blob and then dirty shutdown, reload teh blob store 2074 * and verify the second blob is invalid. 2075 * 5 Create the second blob again and also create the third blob, modify the 2076 * md of second blob which makes the md invalid, and then dirty shutdown, 2077 * reload the blob store verify the second blob, it should invalid and also 2078 * verify the third blob, it should correct. 2079 */ 2080 static void 2081 blob_dirty_shutdown(void) 2082 { 2083 int rc; 2084 int index; 2085 struct spdk_bs_dev *dev; 2086 spdk_blob_id blobid1, blobid2, blobid3; 2087 struct spdk_blob *blob; 2088 uint64_t length; 2089 uint64_t free_clusters; 2090 const void *value; 2091 size_t value_len; 2092 uint32_t page_num; 2093 struct spdk_blob_md_page *page; 2094 struct spdk_bs_opts opts; 2095 2096 dev = init_dev(); 2097 spdk_bs_opts_init(&opts); 2098 /* Initialize a new blob store */ 2099 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2100 CU_ASSERT(g_bserrno == 0); 2101 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2102 2103 /* Create first blob */ 2104 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2105 CU_ASSERT(g_bserrno == 0); 2106 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2107 blobid1 = g_blobid; 2108 2109 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2110 CU_ASSERT(g_bserrno == 0); 2111 CU_ASSERT(g_blob != NULL); 2112 blob = g_blob; 2113 2114 /* Set some xattrs */ 2115 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2116 CU_ASSERT(rc == 0); 2117 2118 length = 2345; 2119 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2120 CU_ASSERT(rc == 0); 2121 2122 /* Resize the blob */ 2123 rc = spdk_blob_resize(blob, 10); 2124 CU_ASSERT(rc == 0); 2125 2126 free_clusters = spdk_bs_free_cluster_count(g_bs); 2127 2128 spdk_blob_close(blob, blob_op_complete, NULL); 2129 blob = NULL; 2130 g_blob = NULL; 2131 g_blobid = SPDK_BLOBID_INVALID; 2132 2133 /* Dirty shutdown */ 2134 _spdk_bs_free(g_bs); 2135 2136 /* reload blobstore */ 2137 dev = init_dev(); 2138 spdk_bs_opts_init(&opts); 2139 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2140 CU_ASSERT(g_bserrno == 0); 2141 2142 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2143 CU_ASSERT(g_bserrno == 0); 2144 CU_ASSERT(g_blob != NULL); 2145 blob = g_blob; 2146 2147 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2148 2149 /* Get the xattrs */ 2150 value = NULL; 2151 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2152 CU_ASSERT(rc == 0); 2153 SPDK_CU_ASSERT_FATAL(value != NULL); 2154 CU_ASSERT(*(uint64_t *)value == length); 2155 CU_ASSERT(value_len == 8); 2156 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2157 2158 /* Resize the blob */ 2159 rc = spdk_blob_resize(blob, 20); 2160 CU_ASSERT(rc == 0); 2161 2162 free_clusters = spdk_bs_free_cluster_count(g_bs); 2163 2164 spdk_blob_close(blob, blob_op_complete, NULL); 2165 CU_ASSERT(g_bserrno == 0); 2166 blob = NULL; 2167 g_blob = NULL; 2168 g_blobid = SPDK_BLOBID_INVALID; 2169 2170 /* Dirty shutdown */ 2171 _spdk_bs_free(g_bs); 2172 2173 /* reload the blobstore */ 2174 dev = init_dev(); 2175 spdk_bs_opts_init(&opts); 2176 /* Load an existing blob store */ 2177 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2178 CU_ASSERT(g_bserrno == 0); 2179 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2180 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2181 CU_ASSERT(g_bserrno == 0); 2182 CU_ASSERT(g_blob != NULL); 2183 blob = g_blob; 2184 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 2185 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2186 2187 spdk_blob_close(blob, blob_op_complete, NULL); 2188 CU_ASSERT(g_bserrno == 0); 2189 blob = NULL; 2190 g_blob = NULL; 2191 g_blobid = SPDK_BLOBID_INVALID; 2192 2193 /* Create second blob */ 2194 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2195 CU_ASSERT(g_bserrno == 0); 2196 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2197 blobid2 = g_blobid; 2198 2199 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2200 CU_ASSERT(g_bserrno == 0); 2201 CU_ASSERT(g_blob != NULL); 2202 blob = g_blob; 2203 2204 /* Set some xattrs */ 2205 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2206 CU_ASSERT(rc == 0); 2207 2208 length = 5432; 2209 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2210 CU_ASSERT(rc == 0); 2211 2212 /* Resize the blob */ 2213 rc = spdk_blob_resize(blob, 10); 2214 CU_ASSERT(rc == 0); 2215 2216 free_clusters = spdk_bs_free_cluster_count(g_bs); 2217 2218 spdk_blob_close(blob, blob_op_complete, NULL); 2219 blob = NULL; 2220 g_blob = NULL; 2221 g_blobid = SPDK_BLOBID_INVALID; 2222 2223 /* Dirty shutdown */ 2224 _spdk_bs_free(g_bs); 2225 2226 /* reload the blobstore */ 2227 dev = init_dev(); 2228 spdk_bs_opts_init(&opts); 2229 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2230 CU_ASSERT(g_bserrno == 0); 2231 2232 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2233 CU_ASSERT(g_bserrno == 0); 2234 CU_ASSERT(g_blob != NULL); 2235 blob = g_blob; 2236 2237 /* Get the xattrs */ 2238 value = NULL; 2239 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2240 CU_ASSERT(rc == 0); 2241 SPDK_CU_ASSERT_FATAL(value != NULL); 2242 CU_ASSERT(*(uint64_t *)value == length); 2243 CU_ASSERT(value_len == 8); 2244 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2245 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2246 2247 spdk_blob_close(blob, blob_op_complete, NULL); 2248 CU_ASSERT(g_bserrno == 0); 2249 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 2250 CU_ASSERT(g_bserrno == 0); 2251 2252 free_clusters = spdk_bs_free_cluster_count(g_bs); 2253 2254 /* Dirty shutdown */ 2255 _spdk_bs_free(g_bs); 2256 /* reload the blobstore */ 2257 dev = init_dev(); 2258 spdk_bs_opts_init(&opts); 2259 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2260 CU_ASSERT(g_bserrno == 0); 2261 2262 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2263 CU_ASSERT(g_bserrno != 0); 2264 CU_ASSERT(g_blob == NULL); 2265 2266 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2267 CU_ASSERT(g_bserrno == 0); 2268 CU_ASSERT(g_blob != NULL); 2269 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2270 spdk_blob_close(g_blob, blob_op_complete, NULL); 2271 CU_ASSERT(g_bserrno == 0); 2272 2273 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2274 CU_ASSERT(g_bserrno == 0); 2275 g_bs = NULL; 2276 2277 /* reload the blobstore */ 2278 dev = init_dev(); 2279 spdk_bs_opts_init(&opts); 2280 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2281 CU_ASSERT(g_bserrno == 0); 2282 2283 /* Create second blob */ 2284 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2285 CU_ASSERT(g_bserrno == 0); 2286 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2287 blobid2 = g_blobid; 2288 2289 /* Create third blob */ 2290 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2291 CU_ASSERT(g_bserrno == 0); 2292 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2293 blobid3 = g_blobid; 2294 2295 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2296 CU_ASSERT(g_bserrno == 0); 2297 CU_ASSERT(g_blob != NULL); 2298 blob = g_blob; 2299 2300 /* Set some xattrs for second blob */ 2301 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2302 CU_ASSERT(rc == 0); 2303 2304 length = 5432; 2305 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2306 CU_ASSERT(rc == 0); 2307 2308 spdk_blob_close(blob, blob_op_complete, NULL); 2309 blob = NULL; 2310 g_blob = NULL; 2311 g_blobid = SPDK_BLOBID_INVALID; 2312 2313 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2314 CU_ASSERT(g_bserrno == 0); 2315 CU_ASSERT(g_blob != NULL); 2316 blob = g_blob; 2317 2318 /* Set some xattrs for third blob */ 2319 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 2320 CU_ASSERT(rc == 0); 2321 2322 length = 5432; 2323 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2324 CU_ASSERT(rc == 0); 2325 2326 spdk_blob_close(blob, blob_op_complete, NULL); 2327 blob = NULL; 2328 g_blob = NULL; 2329 g_blobid = SPDK_BLOBID_INVALID; 2330 2331 /* Mark second blob as invalid */ 2332 page_num = _spdk_bs_blobid_to_page(blobid2); 2333 2334 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 2335 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2336 page->sequence_num = 1; 2337 page->crc = _spdk_blob_md_page_calc_crc(page); 2338 2339 free_clusters = spdk_bs_free_cluster_count(g_bs); 2340 2341 /* Dirty shutdown */ 2342 _spdk_bs_free(g_bs); 2343 /* reload the blobstore */ 2344 dev = init_dev(); 2345 spdk_bs_opts_init(&opts); 2346 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2347 CU_ASSERT(g_bserrno == 0); 2348 2349 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2350 CU_ASSERT(g_bserrno != 0); 2351 CU_ASSERT(g_blob == NULL); 2352 2353 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2354 CU_ASSERT(g_bserrno == 0); 2355 CU_ASSERT(g_blob != NULL); 2356 blob = g_blob; 2357 2358 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2359 2360 spdk_blob_close(blob, blob_op_complete, NULL); 2361 blob = NULL; 2362 g_blob = NULL; 2363 g_blobid = SPDK_BLOBID_INVALID; 2364 2365 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2366 CU_ASSERT(g_bserrno == 0); 2367 g_bs = NULL; 2368 } 2369 2370 static void 2371 blob_flags(void) 2372 { 2373 struct spdk_bs_dev *dev; 2374 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 2375 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 2376 struct spdk_bs_opts opts; 2377 int rc; 2378 2379 dev = init_dev(); 2380 spdk_bs_opts_init(&opts); 2381 2382 /* Initialize a new blob store */ 2383 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2384 CU_ASSERT(g_bserrno == 0); 2385 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2386 2387 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 2388 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2389 CU_ASSERT(g_bserrno == 0); 2390 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2391 blobid_invalid = g_blobid; 2392 2393 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2394 CU_ASSERT(g_bserrno == 0); 2395 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2396 blobid_data_ro = g_blobid; 2397 2398 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2399 CU_ASSERT(g_bserrno == 0); 2400 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2401 blobid_md_ro = g_blobid; 2402 2403 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2404 CU_ASSERT(g_bserrno == 0); 2405 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2406 blob_invalid = g_blob; 2407 2408 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2409 CU_ASSERT(g_bserrno == 0); 2410 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2411 blob_data_ro = g_blob; 2412 2413 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2414 CU_ASSERT(g_bserrno == 0); 2415 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2416 blob_md_ro = g_blob; 2417 2418 /* Change the size of blob_data_ro to check if flags are serialized 2419 * when blob has non zero number of extents */ 2420 rc = spdk_blob_resize(blob_data_ro, 10); 2421 CU_ASSERT(rc == 0); 2422 2423 /* Set the xattr to check if flags are serialized 2424 * when blob has non zero number of xattrs */ 2425 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 2426 CU_ASSERT(rc == 0); 2427 2428 blob_invalid->invalid_flags = (1ULL << 63); 2429 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 2430 blob_data_ro->data_ro_flags = (1ULL << 62); 2431 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 2432 blob_md_ro->md_ro_flags = (1ULL << 61); 2433 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 2434 2435 g_bserrno = -1; 2436 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 2437 CU_ASSERT(g_bserrno == 0); 2438 g_bserrno = -1; 2439 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 2440 CU_ASSERT(g_bserrno == 0); 2441 g_bserrno = -1; 2442 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2443 CU_ASSERT(g_bserrno == 0); 2444 2445 g_bserrno = -1; 2446 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 2447 CU_ASSERT(g_bserrno == 0); 2448 blob_invalid = NULL; 2449 g_bserrno = -1; 2450 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2451 CU_ASSERT(g_bserrno == 0); 2452 blob_data_ro = NULL; 2453 g_bserrno = -1; 2454 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2455 CU_ASSERT(g_bserrno == 0); 2456 blob_md_ro = NULL; 2457 2458 g_blob = NULL; 2459 g_blobid = SPDK_BLOBID_INVALID; 2460 2461 /* Unload the blob store */ 2462 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2463 CU_ASSERT(g_bserrno == 0); 2464 g_bs = NULL; 2465 2466 /* Load an existing blob store */ 2467 dev = init_dev(); 2468 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2469 CU_ASSERT(g_bserrno == 0); 2470 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2471 2472 g_blob = NULL; 2473 g_bserrno = 0; 2474 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2475 CU_ASSERT(g_bserrno != 0); 2476 CU_ASSERT(g_blob == NULL); 2477 2478 g_blob = NULL; 2479 g_bserrno = -1; 2480 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2481 CU_ASSERT(g_bserrno == 0); 2482 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2483 blob_data_ro = g_blob; 2484 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 2485 CU_ASSERT(blob_data_ro->data_ro == true); 2486 CU_ASSERT(blob_data_ro->md_ro == true); 2487 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 2488 2489 g_blob = NULL; 2490 g_bserrno = -1; 2491 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2492 CU_ASSERT(g_bserrno == 0); 2493 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2494 blob_md_ro = g_blob; 2495 CU_ASSERT(blob_md_ro->data_ro == false); 2496 CU_ASSERT(blob_md_ro->md_ro == true); 2497 2498 g_bserrno = -1; 2499 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2500 CU_ASSERT(g_bserrno == 0); 2501 2502 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2503 CU_ASSERT(g_bserrno == 0); 2504 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2505 CU_ASSERT(g_bserrno == 0); 2506 2507 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2508 CU_ASSERT(g_bserrno == 0); 2509 } 2510 2511 static void 2512 bs_version(void) 2513 { 2514 struct spdk_bs_super_block *super; 2515 struct spdk_bs_dev *dev; 2516 struct spdk_bs_opts opts; 2517 spdk_blob_id blobid; 2518 2519 dev = init_dev(); 2520 spdk_bs_opts_init(&opts); 2521 2522 /* Initialize a new blob store */ 2523 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2524 CU_ASSERT(g_bserrno == 0); 2525 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2526 2527 /* Unload the blob store */ 2528 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2529 CU_ASSERT(g_bserrno == 0); 2530 g_bs = NULL; 2531 2532 /* 2533 * Change the bs version on disk. This will allow us to 2534 * test that the version does not get modified automatically 2535 * when loading and unloading the blobstore. 2536 */ 2537 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 2538 CU_ASSERT(super->version == SPDK_BS_VERSION); 2539 CU_ASSERT(super->clean == 1); 2540 super->version = 2; 2541 /* 2542 * Version 2 metadata does not have a used blobid mask, so clear 2543 * those fields in the super block and zero the corresponding 2544 * region on "disk". We will use this to ensure blob IDs are 2545 * correctly reconstructed. 2546 */ 2547 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 2548 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 2549 super->used_blobid_mask_start = 0; 2550 super->used_blobid_mask_len = 0; 2551 super->crc = _spdk_blob_md_page_calc_crc(super); 2552 2553 /* Load an existing blob store */ 2554 dev = init_dev(); 2555 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2556 CU_ASSERT(g_bserrno == 0); 2557 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2558 CU_ASSERT(super->clean == 0); 2559 2560 /* 2561 * Create a blob - just to make sure that when we unload it 2562 * results in writing the super block (since metadata pages 2563 * were allocated. 2564 */ 2565 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2566 CU_ASSERT(g_bserrno == 0); 2567 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2568 blobid = g_blobid; 2569 2570 /* Unload the blob store */ 2571 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2572 CU_ASSERT(g_bserrno == 0); 2573 g_bs = NULL; 2574 CU_ASSERT(super->version == 2); 2575 CU_ASSERT(super->used_blobid_mask_start == 0); 2576 CU_ASSERT(super->used_blobid_mask_len == 0); 2577 2578 dev = init_dev(); 2579 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2580 CU_ASSERT(g_bserrno == 0); 2581 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2582 2583 g_blob = NULL; 2584 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2585 CU_ASSERT(g_bserrno == 0); 2586 CU_ASSERT(g_blob != NULL); 2587 2588 spdk_blob_close(g_blob, blob_op_complete, NULL); 2589 CU_ASSERT(g_bserrno == 0); 2590 2591 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2592 CU_ASSERT(g_bserrno == 0); 2593 g_bs = NULL; 2594 CU_ASSERT(super->version == 2); 2595 CU_ASSERT(super->used_blobid_mask_start == 0); 2596 CU_ASSERT(super->used_blobid_mask_len == 0); 2597 } 2598 2599 static void 2600 _get_xattr_value(void *arg, const char *name, 2601 const void **value, size_t *value_len) 2602 { 2603 uint64_t i; 2604 2605 SPDK_CU_ASSERT_FATAL(value_len != NULL); 2606 SPDK_CU_ASSERT_FATAL(value != NULL); 2607 CU_ASSERT(arg == &g_ctx) 2608 2609 for (i = 0; i < sizeof(g_xattr_names); i++) { 2610 if (!strcmp(name, g_xattr_names[i])) { 2611 *value_len = strlen(g_xattr_values[i]); 2612 *value = g_xattr_values[i]; 2613 break; 2614 } 2615 } 2616 } 2617 2618 static void 2619 _get_xattr_value_null(void *arg, const char *name, 2620 const void **value, size_t *value_len) 2621 { 2622 SPDK_CU_ASSERT_FATAL(value_len != NULL); 2623 SPDK_CU_ASSERT_FATAL(value != NULL); 2624 CU_ASSERT(arg == NULL) 2625 2626 *value_len = 0; 2627 *value = NULL; 2628 } 2629 2630 static void 2631 blob_set_xattrs(void) 2632 { 2633 struct spdk_blob_store *bs; 2634 struct spdk_bs_dev *dev; 2635 struct spdk_blob *blob; 2636 struct spdk_blob_opts opts; 2637 spdk_blob_id blobid; 2638 const void *value; 2639 size_t value_len; 2640 int rc; 2641 2642 dev = init_dev(); 2643 2644 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2645 CU_ASSERT(g_bserrno == 0); 2646 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2647 bs = g_bs; 2648 2649 /* Create blob with extra attributes */ 2650 spdk_blob_opts_init(&opts); 2651 2652 opts.xattrs.names = g_xattr_names; 2653 opts.xattrs.get_value = _get_xattr_value; 2654 opts.xattrs.count = 3; 2655 opts.xattrs.ctx = &g_ctx; 2656 2657 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2658 CU_ASSERT(g_bserrno == 0); 2659 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2660 blobid = g_blobid; 2661 2662 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2663 CU_ASSERT(g_bserrno == 0); 2664 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2665 blob = g_blob; 2666 2667 /* Get the xattrs */ 2668 value = NULL; 2669 2670 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 2671 CU_ASSERT(rc == 0); 2672 SPDK_CU_ASSERT_FATAL(value != NULL); 2673 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 2674 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 2675 2676 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 2677 CU_ASSERT(rc == 0); 2678 SPDK_CU_ASSERT_FATAL(value != NULL); 2679 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 2680 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 2681 2682 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 2683 CU_ASSERT(rc == 0); 2684 SPDK_CU_ASSERT_FATAL(value != NULL); 2685 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 2686 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 2687 2688 /* Try to get non existing attribute */ 2689 2690 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2691 CU_ASSERT(rc == -ENOENT); 2692 2693 spdk_blob_close(blob, blob_op_complete, NULL); 2694 CU_ASSERT(g_bserrno == 0); 2695 blob = NULL; 2696 g_blob = NULL; 2697 g_blobid = SPDK_BLOBID_INVALID; 2698 2699 /* NULL callback */ 2700 spdk_blob_opts_init(&opts); 2701 opts.xattrs.names = g_xattr_names; 2702 opts.xattrs.get_value = NULL; 2703 opts.xattrs.count = 1; 2704 opts.xattrs.ctx = &g_ctx; 2705 2706 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2707 CU_ASSERT(g_bserrno == -EINVAL); 2708 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2709 2710 /* NULL values */ 2711 spdk_blob_opts_init(&opts); 2712 opts.xattrs.names = g_xattr_names; 2713 opts.xattrs.get_value = _get_xattr_value_null; 2714 opts.xattrs.count = 1; 2715 opts.xattrs.ctx = NULL; 2716 2717 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2718 CU_ASSERT(g_bserrno == -EINVAL); 2719 2720 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2721 CU_ASSERT(g_bserrno == 0); 2722 g_bs = NULL; 2723 2724 } 2725 2726 static void 2727 blob_thin_prov_alloc(void) 2728 { 2729 struct spdk_blob_store *bs; 2730 struct spdk_bs_dev *dev; 2731 struct spdk_blob *blob; 2732 struct spdk_blob_opts opts; 2733 spdk_blob_id blobid; 2734 uint64_t free_clusters; 2735 int rc; 2736 2737 dev = init_dev(); 2738 2739 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2740 CU_ASSERT(g_bserrno == 0); 2741 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2742 bs = g_bs; 2743 free_clusters = spdk_bs_free_cluster_count(bs); 2744 2745 /* Set blob as thin provisioned */ 2746 spdk_blob_opts_init(&opts); 2747 opts.thin_provision = true; 2748 2749 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2750 CU_ASSERT(g_bserrno == 0); 2751 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2752 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2753 blobid = g_blobid; 2754 2755 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2756 CU_ASSERT(g_bserrno == 0); 2757 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2758 blob = g_blob; 2759 2760 CU_ASSERT(blob->active.num_clusters == 0); 2761 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 2762 2763 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 2764 rc = spdk_blob_resize(blob, 5); 2765 CU_ASSERT(rc == 0); 2766 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2767 CU_ASSERT(blob->active.num_clusters == 5); 2768 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 2769 2770 /* Shrink the blob to 3 clusters - still unallocated */ 2771 rc = spdk_blob_resize(blob, 3); 2772 CU_ASSERT(rc == 0); 2773 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2774 CU_ASSERT(blob->active.num_clusters == 3); 2775 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 2776 2777 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2778 CU_ASSERT(g_bserrno == 0); 2779 /* Sync must not change anything */ 2780 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2781 CU_ASSERT(blob->active.num_clusters == 3); 2782 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 2783 2784 spdk_blob_close(blob, blob_op_complete, NULL); 2785 CU_ASSERT(g_bserrno == 0); 2786 2787 /* Unload the blob store */ 2788 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2789 CU_ASSERT(g_bserrno == 0); 2790 g_bs = NULL; 2791 g_blob = NULL; 2792 g_blobid = 0; 2793 2794 /* Load an existing blob store */ 2795 dev = init_dev(); 2796 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2797 CU_ASSERT(g_bserrno == 0); 2798 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2799 2800 bs = g_bs; 2801 2802 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2803 CU_ASSERT(g_bserrno == 0); 2804 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2805 blob = g_blob; 2806 2807 /* Check that clusters allocation and size is still the same */ 2808 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2809 CU_ASSERT(blob->active.num_clusters == 3); 2810 2811 spdk_blob_close(blob, blob_op_complete, NULL); 2812 CU_ASSERT(g_bserrno == 0); 2813 2814 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2815 CU_ASSERT(g_bserrno == 0); 2816 2817 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2818 CU_ASSERT(g_bserrno == 0); 2819 g_bs = NULL; 2820 } 2821 2822 static void 2823 blob_insert_cluster_msg(void) 2824 { 2825 struct spdk_blob_store *bs; 2826 struct spdk_bs_dev *dev; 2827 struct spdk_blob *blob; 2828 struct spdk_blob_opts opts; 2829 spdk_blob_id blobid; 2830 uint64_t free_clusters; 2831 2832 dev = init_dev(); 2833 2834 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2835 CU_ASSERT(g_bserrno == 0); 2836 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2837 bs = g_bs; 2838 free_clusters = spdk_bs_free_cluster_count(bs); 2839 2840 /* Set blob as thin provisioned */ 2841 spdk_blob_opts_init(&opts); 2842 opts.thin_provision = true; 2843 opts.num_clusters = 4; 2844 2845 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2846 CU_ASSERT(g_bserrno == 0); 2847 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2848 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2849 blobid = g_blobid; 2850 2851 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2852 CU_ASSERT(g_bserrno == 0); 2853 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2854 blob = g_blob; 2855 2856 CU_ASSERT(blob->active.num_clusters == 4); 2857 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 2858 CU_ASSERT(blob->active.clusters[1] == 0); 2859 2860 _spdk_bs_claim_cluster(bs, 0xF); 2861 _spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL); 2862 2863 CU_ASSERT(blob->active.clusters[1] != 0); 2864 2865 spdk_blob_close(blob, blob_op_complete, NULL); 2866 CU_ASSERT(g_bserrno == 0); 2867 2868 /* Unload the blob store */ 2869 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2870 CU_ASSERT(g_bserrno == 0); 2871 g_bs = NULL; 2872 g_blob = NULL; 2873 g_blobid = 0; 2874 2875 /* Load an existing blob store */ 2876 dev = init_dev(); 2877 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2878 CU_ASSERT(g_bserrno == 0); 2879 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2880 2881 bs = g_bs; 2882 2883 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2884 CU_ASSERT(g_bserrno == 0); 2885 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2886 blob = g_blob; 2887 2888 CU_ASSERT(blob->active.clusters[1] != 0); 2889 2890 spdk_blob_close(blob, blob_op_complete, NULL); 2891 CU_ASSERT(g_bserrno == 0); 2892 2893 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2894 CU_ASSERT(g_bserrno == 0); 2895 2896 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2897 CU_ASSERT(g_bserrno == 0); 2898 g_bs = NULL; 2899 } 2900 2901 static void 2902 blob_thin_prov_rw(void) 2903 { 2904 static const uint8_t zero[10 * 4096] = { 0 }; 2905 struct spdk_blob_store *bs; 2906 struct spdk_bs_dev *dev; 2907 struct spdk_blob *blob; 2908 struct spdk_io_channel *channel; 2909 struct spdk_blob_opts opts; 2910 spdk_blob_id blobid; 2911 uint64_t free_clusters; 2912 uint8_t payload_read[10 * 4096]; 2913 uint8_t payload_write[10 * 4096]; 2914 int rc; 2915 2916 dev = init_dev(); 2917 2918 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2919 CU_ASSERT(g_bserrno == 0); 2920 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2921 bs = g_bs; 2922 free_clusters = spdk_bs_free_cluster_count(bs); 2923 2924 channel = spdk_bs_alloc_io_channel(bs); 2925 CU_ASSERT(channel != NULL); 2926 2927 spdk_blob_opts_init(&opts); 2928 opts.thin_provision = true; 2929 2930 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2931 CU_ASSERT(g_bserrno == 0); 2932 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2933 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2934 blobid = g_blobid; 2935 2936 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2937 CU_ASSERT(g_bserrno == 0); 2938 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2939 blob = g_blob; 2940 2941 CU_ASSERT(blob->active.num_clusters == 0); 2942 2943 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 2944 rc = spdk_blob_resize(blob, 5); 2945 CU_ASSERT(rc == 0); 2946 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2947 CU_ASSERT(blob->active.num_clusters == 5); 2948 2949 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2950 CU_ASSERT(g_bserrno == 0); 2951 /* Sync must not change anything */ 2952 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2953 CU_ASSERT(blob->active.num_clusters == 5); 2954 2955 /* Payload should be all zeros from unallocated clusters */ 2956 memset(payload_read, 0xFF, sizeof(payload_read)); 2957 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 2958 CU_ASSERT(g_bserrno == 0); 2959 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 2960 2961 memset(payload_write, 0xE5, sizeof(payload_write)); 2962 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 2963 CU_ASSERT(g_bserrno == 0); 2964 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 2965 2966 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 2967 CU_ASSERT(g_bserrno == 0); 2968 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 2969 2970 spdk_blob_close(blob, blob_op_complete, NULL); 2971 CU_ASSERT(g_bserrno == 0); 2972 2973 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2974 CU_ASSERT(g_bserrno == 0); 2975 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2976 2977 spdk_bs_free_io_channel(channel); 2978 2979 /* Unload the blob store */ 2980 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2981 CU_ASSERT(g_bserrno == 0); 2982 g_bs = NULL; 2983 g_blob = NULL; 2984 g_blobid = 0; 2985 } 2986 2987 static void 2988 blob_thin_prov_rw_iov(void) 2989 { 2990 static const uint8_t zero[10 * 4096] = { 0 }; 2991 struct spdk_blob_store *bs; 2992 struct spdk_bs_dev *dev; 2993 struct spdk_blob *blob; 2994 struct spdk_io_channel *channel; 2995 struct spdk_blob_opts opts; 2996 spdk_blob_id blobid; 2997 uint64_t free_clusters; 2998 uint8_t payload_read[10 * 4096]; 2999 uint8_t payload_write[10 * 4096]; 3000 struct iovec iov_read[3]; 3001 struct iovec iov_write[3]; 3002 3003 int rc; 3004 3005 dev = init_dev(); 3006 3007 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3008 CU_ASSERT(g_bserrno == 0); 3009 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3010 bs = g_bs; 3011 free_clusters = spdk_bs_free_cluster_count(bs); 3012 3013 channel = spdk_bs_alloc_io_channel(bs); 3014 CU_ASSERT(channel != NULL); 3015 3016 spdk_blob_opts_init(&opts); 3017 opts.thin_provision = true; 3018 3019 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3020 CU_ASSERT(g_bserrno == 0); 3021 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3022 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3023 blobid = g_blobid; 3024 3025 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3026 CU_ASSERT(g_bserrno == 0); 3027 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3028 blob = g_blob; 3029 3030 CU_ASSERT(blob->active.num_clusters == 0); 3031 3032 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3033 rc = spdk_blob_resize(blob, 5); 3034 CU_ASSERT(rc == 0); 3035 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3036 CU_ASSERT(blob->active.num_clusters == 5); 3037 3038 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3039 CU_ASSERT(g_bserrno == 0); 3040 /* Sync must not change anything */ 3041 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3042 CU_ASSERT(blob->active.num_clusters == 5); 3043 3044 /* Payload should be all zeros from unallocated clusters */ 3045 memset(payload_read, 0xAA, sizeof(payload_read)); 3046 iov_read[0].iov_base = payload_read; 3047 iov_read[0].iov_len = 3 * 4096; 3048 iov_read[1].iov_base = payload_read + 3 * 4096; 3049 iov_read[1].iov_len = 4 * 4096; 3050 iov_read[2].iov_base = payload_read + 7 * 4096; 3051 iov_read[2].iov_len = 3 * 4096; 3052 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3053 CU_ASSERT(g_bserrno == 0); 3054 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3055 3056 memset(payload_write, 0xE5, sizeof(payload_write)); 3057 iov_write[0].iov_base = payload_write; 3058 iov_write[0].iov_len = 1 * 4096; 3059 iov_write[1].iov_base = payload_write + 1 * 4096; 3060 iov_write[1].iov_len = 5 * 4096; 3061 iov_write[2].iov_base = payload_write + 6 * 4096; 3062 iov_write[2].iov_len = 4 * 4096; 3063 3064 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 3065 CU_ASSERT(g_bserrno == 0); 3066 3067 memset(payload_read, 0xAA, sizeof(payload_read)); 3068 iov_read[0].iov_base = payload_read; 3069 iov_read[0].iov_len = 3 * 4096; 3070 iov_read[1].iov_base = payload_read + 3 * 4096; 3071 iov_read[1].iov_len = 4 * 4096; 3072 iov_read[2].iov_base = payload_read + 7 * 4096; 3073 iov_read[2].iov_len = 3 * 4096; 3074 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3075 CU_ASSERT(g_bserrno == 0); 3076 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3077 3078 spdk_blob_close(blob, blob_op_complete, NULL); 3079 CU_ASSERT(g_bserrno == 0); 3080 3081 spdk_bs_free_io_channel(channel); 3082 3083 /* Unload the blob store */ 3084 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3085 CU_ASSERT(g_bserrno == 0); 3086 g_bs = NULL; 3087 g_blob = NULL; 3088 g_blobid = 0; 3089 } 3090 3091 struct iter_ctx { 3092 int current_iter; 3093 spdk_blob_id blobid[4]; 3094 }; 3095 3096 static void 3097 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 3098 { 3099 struct iter_ctx *iter_ctx = arg; 3100 spdk_blob_id blobid; 3101 3102 CU_ASSERT(bserrno == 0); 3103 blobid = spdk_blob_get_id(blob); 3104 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 3105 } 3106 3107 static void 3108 bs_load_iter(void) 3109 { 3110 struct spdk_bs_dev *dev; 3111 struct iter_ctx iter_ctx = { 0 }; 3112 struct spdk_blob *blob; 3113 int i, rc; 3114 struct spdk_bs_opts opts; 3115 3116 dev = init_dev(); 3117 spdk_bs_opts_init(&opts); 3118 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 3119 3120 /* Initialize a new blob store */ 3121 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3122 CU_ASSERT(g_bserrno == 0); 3123 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3124 3125 for (i = 0; i < 4; i++) { 3126 g_bserrno = -1; 3127 g_blobid = SPDK_BLOBID_INVALID; 3128 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3129 CU_ASSERT(g_bserrno == 0); 3130 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3131 iter_ctx.blobid[i] = g_blobid; 3132 3133 g_bserrno = -1; 3134 g_blob = NULL; 3135 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 3136 CU_ASSERT(g_bserrno == 0); 3137 CU_ASSERT(g_blob != NULL); 3138 blob = g_blob; 3139 3140 /* Just save the blobid as an xattr for testing purposes. */ 3141 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 3142 CU_ASSERT(rc == 0); 3143 3144 /* Resize the blob */ 3145 rc = spdk_blob_resize(blob, i); 3146 CU_ASSERT(rc == 0); 3147 3148 spdk_blob_close(blob, blob_op_complete, NULL); 3149 CU_ASSERT(g_bserrno == 0); 3150 } 3151 3152 g_bserrno = -1; 3153 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3154 CU_ASSERT(g_bserrno == 0); 3155 3156 dev = init_dev(); 3157 spdk_bs_opts_init(&opts); 3158 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 3159 opts.iter_cb_fn = test_iter; 3160 opts.iter_cb_arg = &iter_ctx; 3161 3162 /* Test blob iteration during load after a clean shutdown. */ 3163 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3164 CU_ASSERT(g_bserrno == 0); 3165 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3166 3167 /* Dirty shutdown */ 3168 _spdk_bs_free(g_bs); 3169 3170 dev = init_dev(); 3171 spdk_bs_opts_init(&opts); 3172 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 3173 opts.iter_cb_fn = test_iter; 3174 iter_ctx.current_iter = 0; 3175 opts.iter_cb_arg = &iter_ctx; 3176 3177 /* Test blob iteration during load after a dirty shutdown. */ 3178 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3179 CU_ASSERT(g_bserrno == 0); 3180 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3181 3182 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3183 CU_ASSERT(g_bserrno == 0); 3184 g_bs = NULL; 3185 3186 } 3187 3188 int main(int argc, char **argv) 3189 { 3190 CU_pSuite suite = NULL; 3191 unsigned int num_failures; 3192 3193 if (CU_initialize_registry() != CUE_SUCCESS) { 3194 return CU_get_error(); 3195 } 3196 3197 suite = CU_add_suite("blob", NULL, NULL); 3198 if (suite == NULL) { 3199 CU_cleanup_registry(); 3200 return CU_get_error(); 3201 } 3202 3203 if ( 3204 CU_add_test(suite, "blob_init", blob_init) == NULL || 3205 CU_add_test(suite, "blob_open", blob_open) == NULL || 3206 CU_add_test(suite, "blob_create", blob_create) == NULL || 3207 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 3208 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 3209 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 3210 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 3211 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 3212 CU_add_test(suite, "blob_super", blob_super) == NULL || 3213 CU_add_test(suite, "blob_write", blob_write) == NULL || 3214 CU_add_test(suite, "blob_read", blob_read) == NULL || 3215 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 3216 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 3217 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 3218 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 3219 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 3220 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 3221 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 3222 CU_add_test(suite, "bs_load", bs_load) == NULL || 3223 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 3224 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 3225 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 3226 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 3227 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 3228 CU_add_test(suite, "bs_type", bs_type) == NULL || 3229 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 3230 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 3231 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 3232 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 3233 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 3234 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 3235 CU_add_test(suite, "bs_version", bs_version) == NULL || 3236 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 3237 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 3238 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 3239 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 3240 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL || 3241 CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL 3242 ) { 3243 CU_cleanup_registry(); 3244 return CU_get_error(); 3245 } 3246 3247 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 3248 spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 3249 CU_basic_set_mode(CU_BRM_VERBOSE); 3250 CU_basic_run_tests(); 3251 num_failures = CU_get_number_of_failures(); 3252 CU_cleanup_registry(); 3253 spdk_free_thread(); 3254 free(g_dev_buffer); 3255 return num_failures; 3256 } 3257