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