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 "blobstore.c" 42 #include "request.c" 43 44 struct spdk_blob_store *g_bs; 45 spdk_blob_id g_blobid; 46 struct spdk_blob *g_blob; 47 int g_bserrno; 48 struct spdk_xattr_names *g_names; 49 int g_done; 50 char *g_xattr_names[] = {"first", "second", "third"}; 51 char *g_xattr_values[] = {"one", "two", "three"}; 52 uint64_t g_ctx = 1729; 53 54 bool g_scheduler_delay = false; 55 56 struct scheduled_ops { 57 spdk_thread_fn fn; 58 void *ctx; 59 60 TAILQ_ENTRY(scheduled_ops) ops_queue; 61 }; 62 63 static TAILQ_HEAD(, scheduled_ops) g_scheduled_ops = TAILQ_HEAD_INITIALIZER(g_scheduled_ops); 64 65 struct spdk_bs_super_block_ver1 { 66 uint8_t signature[8]; 67 uint32_t version; 68 uint32_t length; 69 uint32_t clean; /* If there was a clean shutdown, this is 1. */ 70 spdk_blob_id super_blob; 71 72 uint32_t cluster_size; /* In bytes */ 73 74 uint32_t used_page_mask_start; /* Offset from beginning of disk, in pages */ 75 uint32_t used_page_mask_len; /* Count, in pages */ 76 77 uint32_t used_cluster_mask_start; /* Offset from beginning of disk, in pages */ 78 uint32_t used_cluster_mask_len; /* Count, in pages */ 79 80 uint32_t md_start; /* Offset from beginning of disk, in pages */ 81 uint32_t md_len; /* Count, in pages */ 82 83 uint8_t reserved[4036]; 84 uint32_t crc; 85 } __attribute__((packed)); 86 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size"); 87 88 static void 89 _bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) 90 { 91 if (g_scheduler_delay) { 92 struct scheduled_ops *ops = calloc(1, sizeof(*ops)); 93 94 SPDK_CU_ASSERT_FATAL(ops != NULL); 95 ops->fn = fn; 96 ops->ctx = ctx; 97 TAILQ_INSERT_TAIL(&g_scheduled_ops, ops, ops_queue); 98 } else { 99 fn(ctx); 100 } 101 } 102 103 static void 104 _bs_flush_scheduler(void) 105 { 106 struct scheduled_ops *ops, *tmp; 107 108 TAILQ_FOREACH_SAFE(ops, &g_scheduled_ops, ops_queue, tmp) { 109 ops->fn(ops->ctx); 110 TAILQ_REMOVE(&g_scheduled_ops, ops, ops_queue); 111 free(ops); 112 } 113 } 114 115 static void 116 bs_op_complete(void *cb_arg, int bserrno) 117 { 118 g_bserrno = bserrno; 119 } 120 121 static void 122 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 123 int bserrno) 124 { 125 g_bs = bs; 126 g_bserrno = bserrno; 127 } 128 129 static void 130 blob_op_complete(void *cb_arg, int bserrno) 131 { 132 g_bserrno = bserrno; 133 } 134 135 static void 136 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 137 { 138 g_blobid = blobid; 139 g_bserrno = bserrno; 140 } 141 142 static void 143 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 144 { 145 g_blob = blb; 146 g_bserrno = bserrno; 147 } 148 149 static void 150 blob_init(void) 151 { 152 struct spdk_bs_dev *dev; 153 154 dev = init_dev(); 155 156 /* should fail for an unsupported blocklen */ 157 dev->blocklen = 500; 158 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 159 CU_ASSERT(g_bserrno == -EINVAL); 160 161 dev = init_dev(); 162 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 163 CU_ASSERT(g_bserrno == 0); 164 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 165 166 spdk_bs_unload(g_bs, bs_op_complete, NULL); 167 CU_ASSERT(g_bserrno == 0); 168 g_bs = NULL; 169 } 170 171 static void 172 blob_super(void) 173 { 174 struct spdk_blob_store *bs; 175 struct spdk_bs_dev *dev; 176 spdk_blob_id blobid; 177 178 dev = init_dev(); 179 180 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 181 CU_ASSERT(g_bserrno == 0); 182 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 183 bs = g_bs; 184 185 /* Get the super blob without having set one */ 186 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 187 CU_ASSERT(g_bserrno == -ENOENT); 188 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 189 190 /* Create a blob */ 191 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 192 CU_ASSERT(g_bserrno == 0); 193 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 194 blobid = g_blobid; 195 196 /* Set the blob as the super blob */ 197 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 198 CU_ASSERT(g_bserrno == 0); 199 200 /* Get the super blob */ 201 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 202 CU_ASSERT(g_bserrno == 0); 203 CU_ASSERT(blobid == g_blobid); 204 205 spdk_bs_unload(g_bs, bs_op_complete, NULL); 206 CU_ASSERT(g_bserrno == 0); 207 g_bs = NULL; 208 } 209 210 static void 211 blob_open(void) 212 { 213 struct spdk_blob_store *bs; 214 struct spdk_bs_dev *dev; 215 struct spdk_blob *blob; 216 spdk_blob_id blobid, blobid2; 217 218 dev = init_dev(); 219 220 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 221 CU_ASSERT(g_bserrno == 0); 222 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 223 bs = g_bs; 224 225 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 226 CU_ASSERT(g_bserrno == 0); 227 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 228 blobid = g_blobid; 229 230 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 231 CU_ASSERT(g_bserrno == 0); 232 CU_ASSERT(g_blob != NULL); 233 blob = g_blob; 234 235 blobid2 = spdk_blob_get_id(blob); 236 CU_ASSERT(blobid == blobid2); 237 238 /* Try to open file again. It should return success. */ 239 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 240 CU_ASSERT(g_bserrno == 0); 241 CU_ASSERT(blob == g_blob); 242 243 spdk_blob_close(blob, blob_op_complete, NULL); 244 CU_ASSERT(g_bserrno == 0); 245 246 /* 247 * Close the file a second time, releasing the second reference. This 248 * should succeed. 249 */ 250 blob = g_blob; 251 spdk_blob_close(blob, blob_op_complete, NULL); 252 CU_ASSERT(g_bserrno == 0); 253 254 /* 255 * Try to open file again. It should succeed. This tests the case 256 * where the file is opened, closed, then re-opened again. 257 */ 258 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 259 CU_ASSERT(g_bserrno == 0); 260 CU_ASSERT(g_blob != NULL); 261 blob = g_blob; 262 263 spdk_blob_close(blob, blob_op_complete, NULL); 264 CU_ASSERT(g_bserrno == 0); 265 266 spdk_bs_unload(g_bs, bs_op_complete, NULL); 267 CU_ASSERT(g_bserrno == 0); 268 g_bs = NULL; 269 } 270 271 static void 272 blob_create(void) 273 { 274 struct spdk_blob_store *bs; 275 struct spdk_bs_dev *dev; 276 struct spdk_blob *blob; 277 struct spdk_blob_opts opts; 278 spdk_blob_id blobid; 279 280 dev = init_dev(); 281 282 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 283 CU_ASSERT(g_bserrno == 0); 284 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 285 bs = g_bs; 286 287 /* Create blob with 10 clusters */ 288 289 spdk_blob_opts_init(&opts); 290 opts.num_clusters = 10; 291 292 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 293 CU_ASSERT(g_bserrno == 0); 294 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 295 blobid = g_blobid; 296 297 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 298 CU_ASSERT(g_bserrno == 0); 299 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 300 blob = g_blob; 301 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 302 303 spdk_blob_close(blob, blob_op_complete, NULL); 304 CU_ASSERT(g_bserrno == 0); 305 306 /* Create blob with 0 clusters */ 307 308 spdk_blob_opts_init(&opts); 309 opts.num_clusters = 0; 310 311 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 312 CU_ASSERT(g_bserrno == 0); 313 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 314 blobid = g_blobid; 315 316 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 317 CU_ASSERT(g_bserrno == 0); 318 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 319 blob = g_blob; 320 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 321 322 spdk_blob_close(blob, blob_op_complete, NULL); 323 CU_ASSERT(g_bserrno == 0); 324 325 /* Create blob with default options (opts == NULL) */ 326 327 spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL); 328 CU_ASSERT(g_bserrno == 0); 329 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 330 blobid = g_blobid; 331 332 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 333 CU_ASSERT(g_bserrno == 0); 334 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 335 blob = g_blob; 336 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 337 338 spdk_blob_close(blob, blob_op_complete, NULL); 339 CU_ASSERT(g_bserrno == 0); 340 341 spdk_bs_unload(g_bs, bs_op_complete, NULL); 342 CU_ASSERT(g_bserrno == 0); 343 g_bs = NULL; 344 345 } 346 static void 347 blob_delete(void) 348 { 349 struct spdk_blob_store *bs; 350 struct spdk_bs_dev *dev; 351 spdk_blob_id blobid; 352 353 dev = init_dev(); 354 355 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 356 CU_ASSERT(g_bserrno == 0); 357 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 358 bs = g_bs; 359 360 /* Create a blob and then delete it. */ 361 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 362 CU_ASSERT(g_bserrno == 0); 363 CU_ASSERT(g_blobid > 0); 364 blobid = g_blobid; 365 366 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 367 CU_ASSERT(g_bserrno == 0); 368 369 /* Try to open the blob */ 370 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 371 CU_ASSERT(g_bserrno == -ENOENT); 372 373 spdk_bs_unload(g_bs, bs_op_complete, NULL); 374 CU_ASSERT(g_bserrno == 0); 375 g_bs = NULL; 376 } 377 378 static void 379 blob_resize(void) 380 { 381 struct spdk_blob_store *bs; 382 struct spdk_bs_dev *dev; 383 struct spdk_blob *blob; 384 spdk_blob_id blobid; 385 uint64_t free_clusters; 386 int rc; 387 388 dev = init_dev(); 389 390 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 391 CU_ASSERT(g_bserrno == 0); 392 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 393 bs = g_bs; 394 free_clusters = spdk_bs_free_cluster_count(bs); 395 396 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 397 CU_ASSERT(g_bserrno == 0); 398 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 399 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 400 blobid = g_blobid; 401 402 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 403 CU_ASSERT(g_bserrno == 0); 404 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 405 blob = g_blob; 406 407 /* Confirm that resize fails if blob is marked read-only. */ 408 __blob_to_data(blob)->md_ro = true; 409 rc = spdk_blob_resize(blob, 5); 410 CU_ASSERT(rc == -EPERM); 411 __blob_to_data(blob)->md_ro = false; 412 413 /* The blob started at 0 clusters. Resize it to be 5. */ 414 rc = spdk_blob_resize(blob, 5); 415 CU_ASSERT(rc == 0); 416 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 417 418 /* Shrink the blob to 3 clusters. This will not actually release 419 * the old clusters until the blob is synced. 420 */ 421 rc = spdk_blob_resize(blob, 3); 422 CU_ASSERT(rc == 0); 423 /* Verify there are still 5 clusters in use */ 424 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 425 426 spdk_blob_sync_md(blob, blob_op_complete, NULL); 427 CU_ASSERT(g_bserrno == 0); 428 /* Now there are only 3 clusters in use */ 429 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 430 431 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 432 rc = spdk_blob_resize(blob, 10); 433 CU_ASSERT(rc == 0); 434 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 435 436 spdk_blob_close(blob, blob_op_complete, NULL); 437 CU_ASSERT(g_bserrno == 0); 438 439 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 440 CU_ASSERT(g_bserrno == 0); 441 442 spdk_bs_unload(g_bs, bs_op_complete, NULL); 443 CU_ASSERT(g_bserrno == 0); 444 g_bs = NULL; 445 } 446 447 static void 448 blob_read_only(void) 449 { 450 struct spdk_blob_store *bs; 451 struct spdk_bs_dev *dev; 452 struct spdk_blob *blob; 453 struct spdk_blob_data *blob_data; 454 struct spdk_bs_opts opts; 455 spdk_blob_id blobid; 456 457 dev = init_dev(); 458 spdk_bs_opts_init(&opts); 459 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 460 461 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 462 CU_ASSERT(g_bserrno == 0); 463 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 464 bs = g_bs; 465 466 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 467 CU_ASSERT(g_bserrno == 0); 468 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 469 blobid = g_blobid; 470 471 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 472 CU_ASSERT(g_bserrno == 0); 473 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 474 blob = g_blob; 475 476 spdk_blob_set_read_only(blob); 477 478 blob_data = __blob_to_data(blob); 479 CU_ASSERT(blob_data->data_ro == true); 480 CU_ASSERT(blob_data->data_ro_flags & SPDK_BLOB_READ_ONLY); 481 482 spdk_blob_close(blob, blob_op_complete, NULL); 483 CU_ASSERT(g_bserrno == 0); 484 485 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 486 CU_ASSERT(g_bserrno == 0); 487 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 488 blob = g_blob; 489 490 blob_data = __blob_to_data(blob); 491 CU_ASSERT(blob_data->data_ro == true); 492 CU_ASSERT(blob_data->data_ro_flags & SPDK_BLOB_READ_ONLY); 493 494 spdk_blob_close(blob, blob_op_complete, NULL); 495 CU_ASSERT(g_bserrno == 0); 496 497 spdk_bs_unload(g_bs, bs_op_complete, NULL); 498 CU_ASSERT(g_bserrno == 0); 499 g_bs = NULL; 500 501 } 502 503 static void 504 channel_ops(void) 505 { 506 struct spdk_blob_store *bs; 507 struct spdk_bs_dev *dev; 508 struct spdk_io_channel *channel; 509 510 dev = init_dev(); 511 512 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 513 CU_ASSERT(g_bserrno == 0); 514 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 515 bs = g_bs; 516 517 channel = spdk_bs_alloc_io_channel(bs); 518 CU_ASSERT(channel != NULL); 519 520 spdk_bs_free_io_channel(channel); 521 522 spdk_bs_unload(g_bs, bs_op_complete, NULL); 523 CU_ASSERT(g_bserrno == 0); 524 g_bs = NULL; 525 } 526 527 static void 528 blob_write(void) 529 { 530 struct spdk_blob_store *bs; 531 struct spdk_bs_dev *dev; 532 struct spdk_blob *blob; 533 struct spdk_io_channel *channel; 534 spdk_blob_id blobid; 535 uint64_t pages_per_cluster; 536 uint8_t payload[10 * 4096]; 537 int rc; 538 539 dev = init_dev(); 540 541 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 542 CU_ASSERT(g_bserrno == 0); 543 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 544 bs = g_bs; 545 546 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 547 548 channel = spdk_bs_alloc_io_channel(bs); 549 CU_ASSERT(channel != NULL); 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 /* Write to a blob with 0 size */ 562 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 563 CU_ASSERT(g_bserrno == -EINVAL); 564 565 /* Resize the blob */ 566 rc = spdk_blob_resize(blob, 5); 567 CU_ASSERT(rc == 0); 568 569 /* Confirm that write fails if blob is marked read-only. */ 570 __blob_to_data(blob)->data_ro = true; 571 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 572 CU_ASSERT(g_bserrno == -EPERM); 573 __blob_to_data(blob)->data_ro = false; 574 575 /* Write to the blob */ 576 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 577 CU_ASSERT(g_bserrno == 0); 578 579 /* Write starting beyond the end */ 580 spdk_bs_io_write_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 581 NULL); 582 CU_ASSERT(g_bserrno == -EINVAL); 583 584 /* Write starting at a valid location but going off the end */ 585 spdk_bs_io_write_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 586 blob_op_complete, NULL); 587 CU_ASSERT(g_bserrno == -EINVAL); 588 589 spdk_blob_close(blob, blob_op_complete, NULL); 590 CU_ASSERT(g_bserrno == 0); 591 592 spdk_bs_free_io_channel(channel); 593 594 spdk_bs_unload(g_bs, bs_op_complete, NULL); 595 CU_ASSERT(g_bserrno == 0); 596 g_bs = NULL; 597 } 598 599 static void 600 blob_read(void) 601 { 602 struct spdk_blob_store *bs; 603 struct spdk_bs_dev *dev; 604 struct spdk_blob *blob; 605 struct spdk_io_channel *channel; 606 spdk_blob_id blobid; 607 uint64_t pages_per_cluster; 608 uint8_t payload[10 * 4096]; 609 int rc; 610 611 dev = init_dev(); 612 613 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 614 CU_ASSERT(g_bserrno == 0); 615 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 616 bs = g_bs; 617 618 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 619 620 channel = spdk_bs_alloc_io_channel(bs); 621 CU_ASSERT(channel != NULL); 622 623 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 624 CU_ASSERT(g_bserrno == 0); 625 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 626 blobid = g_blobid; 627 628 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 629 CU_ASSERT(g_bserrno == 0); 630 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 631 blob = g_blob; 632 633 /* Read from a blob with 0 size */ 634 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 635 CU_ASSERT(g_bserrno == -EINVAL); 636 637 /* Resize the blob */ 638 rc = spdk_blob_resize(blob, 5); 639 CU_ASSERT(rc == 0); 640 641 /* Confirm that read passes if blob is marked read-only. */ 642 __blob_to_data(blob)->data_ro = true; 643 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 644 CU_ASSERT(g_bserrno == 0); 645 __blob_to_data(blob)->data_ro = false; 646 647 /* Read from the blob */ 648 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 649 CU_ASSERT(g_bserrno == 0); 650 651 /* Read starting beyond the end */ 652 spdk_bs_io_read_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 653 NULL); 654 CU_ASSERT(g_bserrno == -EINVAL); 655 656 /* Read starting at a valid location but going off the end */ 657 spdk_bs_io_read_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 658 blob_op_complete, NULL); 659 CU_ASSERT(g_bserrno == -EINVAL); 660 661 spdk_blob_close(blob, blob_op_complete, NULL); 662 CU_ASSERT(g_bserrno == 0); 663 664 spdk_bs_free_io_channel(channel); 665 666 spdk_bs_unload(g_bs, bs_op_complete, NULL); 667 CU_ASSERT(g_bserrno == 0); 668 g_bs = NULL; 669 } 670 671 static void 672 blob_rw_verify(void) 673 { 674 struct spdk_blob_store *bs; 675 struct spdk_bs_dev *dev; 676 struct spdk_blob *blob; 677 struct spdk_io_channel *channel; 678 spdk_blob_id blobid; 679 uint8_t payload_read[10 * 4096]; 680 uint8_t payload_write[10 * 4096]; 681 int rc; 682 683 dev = init_dev(); 684 685 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 686 CU_ASSERT(g_bserrno == 0); 687 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 688 bs = g_bs; 689 690 channel = spdk_bs_alloc_io_channel(bs); 691 CU_ASSERT(channel != NULL); 692 693 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 694 CU_ASSERT(g_bserrno == 0); 695 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 696 blobid = g_blobid; 697 698 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 699 CU_ASSERT(g_bserrno == 0); 700 CU_ASSERT(g_blob != NULL); 701 blob = g_blob; 702 703 rc = spdk_blob_resize(blob, 32); 704 CU_ASSERT(rc == 0); 705 706 memset(payload_write, 0xE5, sizeof(payload_write)); 707 spdk_bs_io_write_blob(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 708 CU_ASSERT(g_bserrno == 0); 709 710 memset(payload_read, 0x00, sizeof(payload_read)); 711 spdk_bs_io_read_blob(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 712 CU_ASSERT(g_bserrno == 0); 713 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 714 715 spdk_blob_close(blob, blob_op_complete, NULL); 716 CU_ASSERT(g_bserrno == 0); 717 718 spdk_bs_free_io_channel(channel); 719 720 spdk_bs_unload(g_bs, bs_op_complete, NULL); 721 CU_ASSERT(g_bserrno == 0); 722 g_bs = NULL; 723 } 724 725 static void 726 blob_rw_verify_iov(void) 727 { 728 struct spdk_blob_store *bs; 729 struct spdk_bs_dev *dev; 730 struct spdk_blob *blob; 731 struct spdk_io_channel *channel; 732 spdk_blob_id blobid; 733 uint8_t payload_read[10 * 4096]; 734 uint8_t payload_write[10 * 4096]; 735 struct iovec iov_read[3]; 736 struct iovec iov_write[3]; 737 void *buf; 738 int rc; 739 740 dev = init_dev(); 741 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 742 743 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 744 CU_ASSERT(g_bserrno == 0); 745 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 746 bs = g_bs; 747 748 channel = spdk_bs_alloc_io_channel(bs); 749 CU_ASSERT(channel != NULL); 750 751 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 752 CU_ASSERT(g_bserrno == 0); 753 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 754 blobid = g_blobid; 755 756 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 757 CU_ASSERT(g_bserrno == 0); 758 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 759 blob = g_blob; 760 761 rc = spdk_blob_resize(blob, 2); 762 CU_ASSERT(rc == 0); 763 764 /* 765 * Manually adjust the offset of the blob's second cluster. This allows 766 * us to make sure that the readv/write code correctly accounts for I/O 767 * that cross cluster boundaries. Start by asserting that the allocated 768 * clusters are where we expect before modifying the second cluster. 769 */ 770 CU_ASSERT(__blob_to_data(blob)->active.clusters[0] == 1 * 256); 771 CU_ASSERT(__blob_to_data(blob)->active.clusters[1] == 2 * 256); 772 __blob_to_data(blob)->active.clusters[1] = 3 * 256; 773 774 memset(payload_write, 0xE5, sizeof(payload_write)); 775 iov_write[0].iov_base = payload_write; 776 iov_write[0].iov_len = 1 * 4096; 777 iov_write[1].iov_base = payload_write + 1 * 4096; 778 iov_write[1].iov_len = 5 * 4096; 779 iov_write[2].iov_base = payload_write + 6 * 4096; 780 iov_write[2].iov_len = 4 * 4096; 781 /* 782 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 783 * will get written to the first cluster, the last 4 to the second cluster. 784 */ 785 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 786 CU_ASSERT(g_bserrno == 0); 787 788 memset(payload_read, 0xAA, sizeof(payload_read)); 789 iov_read[0].iov_base = payload_read; 790 iov_read[0].iov_len = 3 * 4096; 791 iov_read[1].iov_base = payload_read + 3 * 4096; 792 iov_read[1].iov_len = 4 * 4096; 793 iov_read[2].iov_base = payload_read + 7 * 4096; 794 iov_read[2].iov_len = 3 * 4096; 795 spdk_bs_io_readv_blob(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 796 CU_ASSERT(g_bserrno == 0); 797 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 798 799 buf = calloc(1, 256 * 4096); 800 SPDK_CU_ASSERT_FATAL(buf != NULL); 801 /* Check that cluster 2 on "disk" was not modified. */ 802 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 803 free(buf); 804 805 spdk_blob_close(blob, blob_op_complete, NULL); 806 CU_ASSERT(g_bserrno == 0); 807 808 spdk_bs_free_io_channel(channel); 809 810 spdk_bs_unload(g_bs, bs_op_complete, NULL); 811 CU_ASSERT(g_bserrno == 0); 812 g_bs = NULL; 813 } 814 815 static uint32_t 816 bs_channel_get_req_count(struct spdk_io_channel *_channel) 817 { 818 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 819 struct spdk_bs_request_set *set; 820 uint32_t count = 0; 821 822 TAILQ_FOREACH(set, &channel->reqs, link) { 823 count++; 824 } 825 826 return count; 827 } 828 829 static void 830 blob_rw_verify_iov_nomem(void) 831 { 832 struct spdk_blob_store *bs; 833 struct spdk_bs_dev *dev; 834 struct spdk_blob *blob; 835 struct spdk_io_channel *channel; 836 spdk_blob_id blobid; 837 uint8_t payload_write[10 * 4096]; 838 struct iovec iov_write[3]; 839 uint32_t req_count; 840 int rc; 841 842 dev = init_dev(); 843 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 844 845 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 846 CU_ASSERT(g_bserrno == 0); 847 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 848 bs = g_bs; 849 850 channel = spdk_bs_alloc_io_channel(bs); 851 CU_ASSERT(channel != NULL); 852 853 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 854 CU_ASSERT(g_bserrno == 0); 855 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 856 blobid = g_blobid; 857 858 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 859 CU_ASSERT(g_bserrno == 0); 860 CU_ASSERT(g_blob != NULL); 861 blob = g_blob; 862 863 rc = spdk_blob_resize(blob, 2); 864 CU_ASSERT(rc == 0); 865 866 /* 867 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 868 * will get written to the first cluster, the last 4 to the second cluster. 869 */ 870 iov_write[0].iov_base = payload_write; 871 iov_write[0].iov_len = 1 * 4096; 872 iov_write[1].iov_base = payload_write + 1 * 4096; 873 iov_write[1].iov_len = 5 * 4096; 874 iov_write[2].iov_base = payload_write + 6 * 4096; 875 iov_write[2].iov_len = 4 * 4096; 876 MOCK_SET(calloc, void *, NULL); 877 req_count = bs_channel_get_req_count(channel); 878 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 879 CU_ASSERT(g_bserrno = -ENOMEM); 880 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 881 MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU); 882 883 spdk_blob_close(blob, blob_op_complete, NULL); 884 CU_ASSERT(g_bserrno == 0); 885 886 spdk_bs_free_io_channel(channel); 887 888 spdk_bs_unload(g_bs, bs_op_complete, NULL); 889 CU_ASSERT(g_bserrno == 0); 890 g_bs = NULL; 891 } 892 893 static void 894 blob_rw_iov_read_only(void) 895 { 896 struct spdk_blob_store *bs; 897 struct spdk_bs_dev *dev; 898 struct spdk_blob *blob; 899 struct spdk_io_channel *channel; 900 spdk_blob_id blobid; 901 uint8_t payload_read[4096]; 902 uint8_t payload_write[4096]; 903 struct iovec iov_read; 904 struct iovec iov_write; 905 int rc; 906 907 dev = init_dev(); 908 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 909 910 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 911 CU_ASSERT(g_bserrno == 0); 912 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 913 bs = g_bs; 914 915 channel = spdk_bs_alloc_io_channel(bs); 916 CU_ASSERT(channel != NULL); 917 918 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 919 CU_ASSERT(g_bserrno == 0); 920 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 921 blobid = g_blobid; 922 923 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 924 CU_ASSERT(g_bserrno == 0); 925 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 926 blob = g_blob; 927 928 rc = spdk_blob_resize(blob, 2); 929 CU_ASSERT(rc == 0); 930 931 /* Verify that writev failed if read_only flag is set. */ 932 __blob_to_data(blob)->data_ro = true; 933 iov_write.iov_base = payload_write; 934 iov_write.iov_len = sizeof(payload_write); 935 spdk_bs_io_writev_blob(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL); 936 CU_ASSERT(g_bserrno == -EPERM); 937 938 /* Verify that reads pass if data_ro flag is set. */ 939 iov_read.iov_base = payload_read; 940 iov_read.iov_len = sizeof(payload_read); 941 spdk_bs_io_readv_blob(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL); 942 CU_ASSERT(g_bserrno == 0); 943 944 spdk_blob_close(blob, blob_op_complete, NULL); 945 CU_ASSERT(g_bserrno == 0); 946 947 spdk_bs_free_io_channel(channel); 948 949 spdk_bs_unload(g_bs, bs_op_complete, NULL); 950 CU_ASSERT(g_bserrno == 0); 951 g_bs = NULL; 952 } 953 954 static void 955 blob_iter(void) 956 { 957 struct spdk_blob_store *bs; 958 struct spdk_bs_dev *dev; 959 struct spdk_blob *blob; 960 spdk_blob_id blobid; 961 962 dev = init_dev(); 963 964 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 965 CU_ASSERT(g_bserrno == 0); 966 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 967 bs = g_bs; 968 969 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 970 CU_ASSERT(g_blob == NULL); 971 CU_ASSERT(g_bserrno == -ENOENT); 972 973 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 974 CU_ASSERT(g_bserrno == 0); 975 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 976 blobid = g_blobid; 977 978 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 979 CU_ASSERT(g_blob != NULL); 980 CU_ASSERT(g_bserrno == 0); 981 blob = g_blob; 982 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 983 984 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 985 CU_ASSERT(g_blob == NULL); 986 CU_ASSERT(g_bserrno == -ENOENT); 987 988 spdk_bs_unload(g_bs, bs_op_complete, NULL); 989 CU_ASSERT(g_bserrno == 0); 990 g_bs = NULL; 991 } 992 993 static void 994 blob_xattr(void) 995 { 996 struct spdk_blob_store *bs; 997 struct spdk_bs_dev *dev; 998 struct spdk_blob *blob; 999 spdk_blob_id blobid; 1000 uint64_t length; 1001 int rc; 1002 const char *name1, *name2; 1003 const void *value; 1004 size_t value_len; 1005 struct spdk_xattr_names *names; 1006 1007 dev = init_dev(); 1008 1009 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1010 CU_ASSERT(g_bserrno == 0); 1011 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1012 bs = g_bs; 1013 1014 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1015 CU_ASSERT(g_bserrno == 0); 1016 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1017 blobid = g_blobid; 1018 1019 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1020 CU_ASSERT(g_bserrno == 0); 1021 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1022 blob = g_blob; 1023 1024 /* Test that set_xattr fails if md_ro flag is set. */ 1025 __blob_to_data(blob)->md_ro = true; 1026 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1027 CU_ASSERT(rc == -EPERM); 1028 1029 __blob_to_data(blob)->md_ro = false; 1030 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1031 CU_ASSERT(rc == 0); 1032 1033 length = 2345; 1034 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1035 CU_ASSERT(rc == 0); 1036 1037 /* Overwrite "length" xattr. */ 1038 length = 3456; 1039 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1040 CU_ASSERT(rc == 0); 1041 1042 /* get_xattr should still work even if md_ro flag is set. */ 1043 value = NULL; 1044 __blob_to_data(blob)->md_ro = true; 1045 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1046 CU_ASSERT(rc == 0); 1047 SPDK_CU_ASSERT_FATAL(value != NULL); 1048 CU_ASSERT(*(uint64_t *)value == length); 1049 CU_ASSERT(value_len == 8); 1050 __blob_to_data(blob)->md_ro = false; 1051 1052 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1053 CU_ASSERT(rc == -ENOENT); 1054 1055 names = NULL; 1056 rc = spdk_blob_get_xattr_names(blob, &names); 1057 CU_ASSERT(rc == 0); 1058 SPDK_CU_ASSERT_FATAL(names != NULL); 1059 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 1060 name1 = spdk_xattr_names_get_name(names, 0); 1061 SPDK_CU_ASSERT_FATAL(name1 != NULL); 1062 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 1063 name2 = spdk_xattr_names_get_name(names, 1); 1064 SPDK_CU_ASSERT_FATAL(name2 != NULL); 1065 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 1066 CU_ASSERT(strcmp(name1, name2)); 1067 spdk_xattr_names_free(names); 1068 1069 /* Confirm that remove_xattr fails if md_ro is set to true. */ 1070 __blob_to_data(blob)->md_ro = true; 1071 rc = spdk_blob_remove_xattr(blob, "name"); 1072 CU_ASSERT(rc == -EPERM); 1073 1074 __blob_to_data(blob)->md_ro = false; 1075 rc = spdk_blob_remove_xattr(blob, "name"); 1076 CU_ASSERT(rc == 0); 1077 1078 rc = spdk_blob_remove_xattr(blob, "foobar"); 1079 CU_ASSERT(rc == -ENOENT); 1080 1081 spdk_blob_close(blob, blob_op_complete, NULL); 1082 1083 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1084 CU_ASSERT(g_bserrno == 0); 1085 g_bs = NULL; 1086 } 1087 1088 static void 1089 bs_load(void) 1090 { 1091 struct spdk_bs_dev *dev; 1092 spdk_blob_id blobid; 1093 struct spdk_blob *blob; 1094 struct spdk_bs_super_block *super_block; 1095 uint64_t length; 1096 int rc; 1097 const void *value; 1098 size_t value_len; 1099 struct spdk_bs_opts opts; 1100 1101 g_scheduler_delay = true; 1102 1103 dev = init_dev(); 1104 spdk_bs_opts_init(&opts); 1105 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1106 1107 /* Initialize a new blob store */ 1108 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1109 CU_ASSERT(g_bserrno == 0); 1110 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1111 1112 /* Try to open a blobid that does not exist */ 1113 spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 1114 CU_ASSERT(g_bserrno == -ENOENT); 1115 CU_ASSERT(g_blob == NULL); 1116 1117 /* Create a blob */ 1118 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1119 CU_ASSERT(g_bserrno == 0); 1120 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1121 blobid = g_blobid; 1122 1123 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1124 CU_ASSERT(g_bserrno == 0); 1125 CU_ASSERT(g_blob != NULL); 1126 blob = g_blob; 1127 1128 /* Try again to open valid blob but without the upper bit set */ 1129 spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 1130 CU_ASSERT(g_bserrno == -ENOENT); 1131 CU_ASSERT(g_blob == NULL); 1132 1133 /* Set some xattrs */ 1134 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1135 CU_ASSERT(rc == 0); 1136 1137 length = 2345; 1138 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1139 CU_ASSERT(rc == 0); 1140 1141 /* Resize the blob */ 1142 rc = spdk_blob_resize(blob, 10); 1143 CU_ASSERT(rc == 0); 1144 1145 spdk_blob_close(blob, blob_op_complete, NULL); 1146 CU_ASSERT(g_bserrno == 0); 1147 blob = NULL; 1148 g_blob = NULL; 1149 g_blobid = SPDK_BLOBID_INVALID; 1150 1151 /* Unload the blob store */ 1152 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1153 CU_ASSERT(g_bserrno == 0); 1154 g_bs = NULL; 1155 g_blob = NULL; 1156 g_blobid = 0; 1157 1158 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1159 CU_ASSERT(super_block->clean == 1); 1160 1161 1162 /* Load an existing blob store */ 1163 dev = init_dev(); 1164 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1165 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1166 CU_ASSERT(g_bserrno == 0); 1167 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1168 1169 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1170 CU_ASSERT(super_block->clean == 0); 1171 1172 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1173 CU_ASSERT(g_bserrno == 0); 1174 CU_ASSERT(g_blob != NULL); 1175 blob = g_blob; 1176 1177 /* Get the xattrs */ 1178 value = NULL; 1179 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1180 CU_ASSERT(rc == 0); 1181 SPDK_CU_ASSERT_FATAL(value != NULL); 1182 CU_ASSERT(*(uint64_t *)value == length); 1183 CU_ASSERT(value_len == 8); 1184 1185 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1186 CU_ASSERT(rc == -ENOENT); 1187 1188 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1189 1190 spdk_blob_close(blob, blob_op_complete, NULL); 1191 CU_ASSERT(g_bserrno == 0); 1192 blob = NULL; 1193 g_blob = NULL; 1194 g_blobid = SPDK_BLOBID_INVALID; 1195 1196 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1197 CU_ASSERT(g_bserrno == 0); 1198 g_bs = NULL; 1199 g_scheduler_delay = false; 1200 } 1201 1202 static void 1203 bs_type(void) 1204 { 1205 struct spdk_bs_dev *dev; 1206 struct spdk_bs_opts opts; 1207 1208 g_scheduler_delay = true; 1209 1210 dev = init_dev(); 1211 spdk_bs_opts_init(&opts); 1212 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1213 1214 /* Initialize a new blob store */ 1215 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1216 CU_ASSERT(g_bserrno == 0); 1217 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1218 1219 /* Unload the blob store */ 1220 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1221 CU_ASSERT(g_bserrno == 0); 1222 g_bs = NULL; 1223 g_blob = NULL; 1224 g_blobid = 0; 1225 1226 /* Load non existing blobstore type */ 1227 dev = init_dev(); 1228 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1229 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1230 CU_ASSERT(g_bserrno != 0); 1231 1232 /* Load with empty blobstore type */ 1233 dev = init_dev(); 1234 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1235 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1236 CU_ASSERT(g_bserrno == 0); 1237 1238 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1239 CU_ASSERT(g_bserrno == 0); 1240 g_bs = NULL; 1241 1242 /* Initialize a new blob store with empty bstype */ 1243 dev = init_dev(); 1244 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1245 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1246 CU_ASSERT(g_bserrno == 0); 1247 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1248 1249 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1250 CU_ASSERT(g_bserrno == 0); 1251 g_bs = NULL; 1252 1253 /* Load non existing blobstore type */ 1254 dev = init_dev(); 1255 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1256 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1257 CU_ASSERT(g_bserrno != 0); 1258 1259 /* Load with empty blobstore type */ 1260 dev = init_dev(); 1261 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1262 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1263 CU_ASSERT(g_bserrno == 0); 1264 1265 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1266 CU_ASSERT(g_bserrno == 0); 1267 g_bs = NULL; 1268 g_scheduler_delay = false; 1269 } 1270 1271 static void 1272 bs_super_block(void) 1273 { 1274 struct spdk_bs_dev *dev; 1275 struct spdk_bs_super_block *super_block; 1276 struct spdk_bs_opts opts; 1277 struct spdk_bs_super_block_ver1 super_block_v1; 1278 1279 g_scheduler_delay = true; 1280 1281 dev = init_dev(); 1282 spdk_bs_opts_init(&opts); 1283 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1284 1285 /* Initialize a new blob store */ 1286 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1287 CU_ASSERT(g_bserrno == 0); 1288 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1289 1290 /* Unload the blob store */ 1291 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1292 CU_ASSERT(g_bserrno == 0); 1293 g_bs = NULL; 1294 g_blob = NULL; 1295 g_blobid = 0; 1296 1297 /* Load an existing blob store with version newer than supported */ 1298 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1299 super_block->version++; 1300 1301 dev = init_dev(); 1302 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1303 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1304 CU_ASSERT(g_bserrno != 0); 1305 1306 /* Create a new blob store with super block version 1 */ 1307 dev = init_dev(); 1308 super_block_v1.version = 1; 1309 strncpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 1310 super_block_v1.length = 0x1000; 1311 super_block_v1.clean = 1; 1312 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 1313 super_block_v1.cluster_size = 0x100000; 1314 super_block_v1.used_page_mask_start = 0x01; 1315 super_block_v1.used_page_mask_len = 0x01; 1316 super_block_v1.used_cluster_mask_start = 0x02; 1317 super_block_v1.used_cluster_mask_len = 0x01; 1318 super_block_v1.md_start = 0x03; 1319 super_block_v1.md_len = 0x40; 1320 memset(super_block_v1.reserved, 0, 4036); 1321 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 1322 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 1323 1324 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1325 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1326 CU_ASSERT(g_bserrno == 0); 1327 1328 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1329 CU_ASSERT(g_bserrno == 0); 1330 g_bs = NULL; 1331 g_scheduler_delay = false; 1332 } 1333 1334 /* 1335 * Create a blobstore and then unload it. 1336 */ 1337 static void 1338 bs_unload(void) 1339 { 1340 struct spdk_bs_dev *dev; 1341 struct spdk_blob_store *bs; 1342 spdk_blob_id blobid; 1343 struct spdk_blob *blob; 1344 1345 dev = init_dev(); 1346 1347 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1348 CU_ASSERT(g_bserrno == 0); 1349 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1350 bs = g_bs; 1351 1352 /* Create a blob and open it. */ 1353 g_bserrno = -1; 1354 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1355 CU_ASSERT(g_bserrno == 0); 1356 CU_ASSERT(g_blobid > 0); 1357 blobid = g_blobid; 1358 1359 g_bserrno = -1; 1360 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1361 CU_ASSERT(g_bserrno == 0); 1362 CU_ASSERT(g_blob != NULL); 1363 blob = g_blob; 1364 1365 /* Try to unload blobstore, should fail with open blob */ 1366 g_bserrno = -1; 1367 spdk_bs_unload(bs, bs_op_complete, NULL); 1368 CU_ASSERT(g_bserrno == -EBUSY); 1369 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1370 1371 /* Close the blob, then successfully unload blobstore */ 1372 g_bserrno = -1; 1373 spdk_blob_close(blob, blob_op_complete, NULL); 1374 CU_ASSERT(g_bserrno == 0); 1375 1376 g_bserrno = -1; 1377 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1378 CU_ASSERT(g_bserrno == 0); 1379 g_bs = NULL; 1380 } 1381 1382 /* 1383 * Create a blobstore with a cluster size different than the default, and ensure it is 1384 * persisted. 1385 */ 1386 static void 1387 bs_cluster_sz(void) 1388 { 1389 struct spdk_bs_dev *dev; 1390 struct spdk_bs_opts opts; 1391 uint32_t cluster_sz; 1392 1393 /* Set cluster size to zero */ 1394 dev = init_dev(); 1395 spdk_bs_opts_init(&opts); 1396 opts.cluster_sz = 0; 1397 1398 /* Initialize a new blob store */ 1399 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1400 CU_ASSERT(g_bserrno == -EINVAL); 1401 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1402 1403 /* 1404 * Set cluster size to blobstore page size, 1405 * to work it is required to be at least twice the blobstore page size. 1406 */ 1407 dev = init_dev(); 1408 spdk_bs_opts_init(&opts); 1409 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 1410 1411 /* Initialize a new blob store */ 1412 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1413 CU_ASSERT(g_bserrno == -ENOMEM); 1414 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1415 1416 /* 1417 * Set cluster size to lower than page size, 1418 * to work it is required to be at least twice the blobstore page size. 1419 */ 1420 dev = init_dev(); 1421 spdk_bs_opts_init(&opts); 1422 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 1423 1424 /* Initialize a new blob store */ 1425 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1426 CU_ASSERT(g_bserrno == -ENOMEM); 1427 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1428 1429 /* Set cluster size to twice the default */ 1430 dev = init_dev(); 1431 spdk_bs_opts_init(&opts); 1432 opts.cluster_sz *= 2; 1433 cluster_sz = opts.cluster_sz; 1434 1435 /* Initialize a new blob store */ 1436 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1437 CU_ASSERT(g_bserrno == 0); 1438 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1439 1440 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1441 1442 /* Unload the blob store */ 1443 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1444 CU_ASSERT(g_bserrno == 0); 1445 g_bs = NULL; 1446 g_blob = NULL; 1447 g_blobid = 0; 1448 1449 dev = init_dev(); 1450 /* Load an existing blob store */ 1451 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1452 CU_ASSERT(g_bserrno == 0); 1453 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1454 1455 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1456 1457 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1458 CU_ASSERT(g_bserrno == 0); 1459 g_bs = NULL; 1460 } 1461 1462 /* 1463 * Create a blobstore, reload it and ensure total usable cluster count 1464 * stays the same. 1465 */ 1466 static void 1467 bs_usable_clusters(void) 1468 { 1469 struct spdk_bs_dev *dev; 1470 struct spdk_bs_opts opts; 1471 uint32_t clusters; 1472 int i, rc; 1473 1474 /* Init blobstore */ 1475 dev = init_dev(); 1476 spdk_bs_opts_init(&opts); 1477 1478 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1479 CU_ASSERT(g_bserrno == 0); 1480 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1481 1482 clusters = spdk_bs_total_data_cluster_count(g_bs); 1483 1484 /* Unload the blob store */ 1485 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1486 CU_ASSERT(g_bserrno == 0); 1487 g_bs = NULL; 1488 1489 dev = init_dev(); 1490 /* Load an existing blob store */ 1491 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1492 CU_ASSERT(g_bserrno == 0); 1493 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1494 1495 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1496 1497 /* Create and resize blobs to make sure that useable cluster count won't change */ 1498 for (i = 0; i < 4; i++) { 1499 g_bserrno = -1; 1500 g_blobid = SPDK_BLOBID_INVALID; 1501 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1502 CU_ASSERT(g_bserrno == 0); 1503 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1504 1505 g_bserrno = -1; 1506 g_blob = NULL; 1507 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 1508 CU_ASSERT(g_bserrno == 0); 1509 CU_ASSERT(g_blob != NULL); 1510 1511 rc = spdk_blob_resize(g_blob, 10); 1512 CU_ASSERT(rc == 0); 1513 1514 g_bserrno = -1; 1515 spdk_blob_close(g_blob, blob_op_complete, NULL); 1516 CU_ASSERT(g_bserrno == 0); 1517 1518 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1519 } 1520 1521 /* Reload the blob store to make sure that nothing changed */ 1522 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1523 CU_ASSERT(g_bserrno == 0); 1524 g_bs = NULL; 1525 1526 dev = init_dev(); 1527 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1528 CU_ASSERT(g_bserrno == 0); 1529 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1530 1531 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1532 1533 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1534 CU_ASSERT(g_bserrno == 0); 1535 g_bs = NULL; 1536 } 1537 1538 /* 1539 * Test resizing of the metadata blob. This requires creating enough blobs 1540 * so that one cluster is not enough to fit the metadata for those blobs. 1541 * To induce this condition to happen more quickly, we reduce the cluster 1542 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 1543 */ 1544 static void 1545 bs_resize_md(void) 1546 { 1547 const int CLUSTER_PAGE_COUNT = 4; 1548 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 1549 struct spdk_bs_dev *dev; 1550 struct spdk_bs_opts opts; 1551 uint32_t cluster_sz; 1552 spdk_blob_id blobids[NUM_BLOBS]; 1553 int i; 1554 1555 1556 dev = init_dev(); 1557 spdk_bs_opts_init(&opts); 1558 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 1559 cluster_sz = opts.cluster_sz; 1560 1561 /* Initialize a new blob store */ 1562 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1563 CU_ASSERT(g_bserrno == 0); 1564 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1565 1566 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1567 1568 for (i = 0; i < NUM_BLOBS; i++) { 1569 g_bserrno = -1; 1570 g_blobid = SPDK_BLOBID_INVALID; 1571 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1572 CU_ASSERT(g_bserrno == 0); 1573 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1574 blobids[i] = g_blobid; 1575 } 1576 1577 /* Unload the blob store */ 1578 g_bserrno = -1; 1579 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1580 CU_ASSERT(g_bserrno == 0); 1581 1582 /* Load an existing blob store */ 1583 g_bserrno = -1; 1584 g_bs = NULL; 1585 dev = init_dev(); 1586 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1587 CU_ASSERT(g_bserrno == 0); 1588 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1589 1590 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1591 1592 for (i = 0; i < NUM_BLOBS; i++) { 1593 g_bserrno = -1; 1594 g_blob = NULL; 1595 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 1596 CU_ASSERT(g_bserrno == 0); 1597 CU_ASSERT(g_blob != NULL); 1598 g_bserrno = -1; 1599 spdk_blob_close(g_blob, blob_op_complete, NULL); 1600 CU_ASSERT(g_bserrno == 0); 1601 } 1602 1603 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1604 CU_ASSERT(g_bserrno == 0); 1605 g_bs = NULL; 1606 } 1607 1608 static void 1609 bs_destroy(void) 1610 { 1611 struct spdk_bs_dev *dev; 1612 struct spdk_bs_opts opts; 1613 1614 g_scheduler_delay = true; 1615 1616 _bs_flush_scheduler(); 1617 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1618 1619 /* Initialize a new blob store */ 1620 dev = init_dev(); 1621 spdk_bs_opts_init(&opts); 1622 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1623 CU_ASSERT(g_bserrno == 0); 1624 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1625 1626 /* Destroy the blob store */ 1627 g_bserrno = -1; 1628 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 1629 /* Callback is called after device is destroyed in next scheduler run. */ 1630 _bs_flush_scheduler(); 1631 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1632 CU_ASSERT(g_bserrno == 0); 1633 1634 /* Loading an non-existent blob store should fail. */ 1635 g_bserrno = -1; 1636 g_bs = NULL; 1637 dev = init_dev(); 1638 1639 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1640 CU_ASSERT(g_bserrno != 0); 1641 g_scheduler_delay = false; 1642 } 1643 1644 /* Try to hit all of the corner cases associated with serializing 1645 * a blob to disk 1646 */ 1647 static void 1648 blob_serialize(void) 1649 { 1650 struct spdk_bs_dev *dev; 1651 struct spdk_bs_opts opts; 1652 struct spdk_blob_store *bs; 1653 spdk_blob_id blobid[2]; 1654 struct spdk_blob *blob[2]; 1655 uint64_t i; 1656 char *value; 1657 int rc; 1658 1659 dev = init_dev(); 1660 1661 /* Initialize a new blobstore with very small clusters */ 1662 spdk_bs_opts_init(&opts); 1663 opts.cluster_sz = dev->blocklen * 8; 1664 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1665 CU_ASSERT(g_bserrno == 0); 1666 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1667 bs = g_bs; 1668 1669 /* Create and open two blobs */ 1670 for (i = 0; i < 2; i++) { 1671 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1672 CU_ASSERT(g_bserrno == 0); 1673 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1674 blobid[i] = g_blobid; 1675 1676 /* Open a blob */ 1677 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1678 CU_ASSERT(g_bserrno == 0); 1679 CU_ASSERT(g_blob != NULL); 1680 blob[i] = g_blob; 1681 1682 /* Set a fairly large xattr on both blobs to eat up 1683 * metadata space 1684 */ 1685 value = calloc(dev->blocklen - 64, sizeof(char)); 1686 SPDK_CU_ASSERT_FATAL(value != NULL); 1687 memset(value, i, dev->blocklen / 2); 1688 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 1689 CU_ASSERT(rc == 0); 1690 free(value); 1691 } 1692 1693 /* Resize the blobs, alternating 1 cluster at a time. 1694 * This thwarts run length encoding and will cause spill 1695 * over of the extents. 1696 */ 1697 for (i = 0; i < 6; i++) { 1698 rc = spdk_blob_resize(blob[i % 2], (i / 2) + 1); 1699 CU_ASSERT(rc == 0); 1700 } 1701 1702 for (i = 0; i < 2; i++) { 1703 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 1704 CU_ASSERT(g_bserrno == 0); 1705 } 1706 1707 /* Close the blobs */ 1708 for (i = 0; i < 2; i++) { 1709 spdk_blob_close(blob[i], blob_op_complete, NULL); 1710 CU_ASSERT(g_bserrno == 0); 1711 } 1712 1713 /* Unload the blobstore */ 1714 spdk_bs_unload(bs, bs_op_complete, NULL); 1715 CU_ASSERT(g_bserrno == 0); 1716 g_bs = NULL; 1717 g_blob = NULL; 1718 g_blobid = 0; 1719 bs = NULL; 1720 1721 dev = init_dev(); 1722 /* Load an existing blob store */ 1723 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1724 CU_ASSERT(g_bserrno == 0); 1725 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1726 bs = g_bs; 1727 1728 for (i = 0; i < 2; i++) { 1729 blob[i] = NULL; 1730 1731 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1732 CU_ASSERT(g_bserrno == 0); 1733 CU_ASSERT(g_blob != NULL); 1734 blob[i] = g_blob; 1735 1736 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 1737 1738 spdk_blob_close(blob[i], blob_op_complete, NULL); 1739 CU_ASSERT(g_bserrno == 0); 1740 } 1741 1742 spdk_bs_unload(bs, bs_op_complete, NULL); 1743 CU_ASSERT(g_bserrno == 0); 1744 g_bs = NULL; 1745 } 1746 1747 static void 1748 blob_crc(void) 1749 { 1750 struct spdk_blob_store *bs; 1751 struct spdk_bs_dev *dev; 1752 struct spdk_blob *blob; 1753 spdk_blob_id blobid; 1754 uint32_t page_num; 1755 int index; 1756 struct spdk_blob_md_page *page; 1757 1758 dev = init_dev(); 1759 1760 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1761 CU_ASSERT(g_bserrno == 0); 1762 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1763 bs = g_bs; 1764 1765 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1766 CU_ASSERT(g_bserrno == 0); 1767 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1768 blobid = g_blobid; 1769 1770 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1771 CU_ASSERT(g_bserrno == 0); 1772 CU_ASSERT(g_blob != NULL); 1773 blob = g_blob; 1774 1775 spdk_blob_close(blob, blob_op_complete, NULL); 1776 CU_ASSERT(g_bserrno == 0); 1777 1778 page_num = _spdk_bs_blobid_to_page(blobid); 1779 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 1780 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 1781 page->crc = 0; 1782 1783 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1784 CU_ASSERT(g_bserrno == -EINVAL); 1785 CU_ASSERT(g_blob == NULL); 1786 g_bserrno = 0; 1787 1788 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 1789 CU_ASSERT(g_bserrno == -EINVAL); 1790 1791 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1792 CU_ASSERT(g_bserrno == 0); 1793 g_bs = NULL; 1794 } 1795 1796 static void 1797 super_block_crc(void) 1798 { 1799 struct spdk_bs_dev *dev; 1800 struct spdk_bs_super_block *super_block; 1801 struct spdk_bs_opts opts; 1802 1803 dev = init_dev(); 1804 spdk_bs_opts_init(&opts); 1805 1806 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1807 CU_ASSERT(g_bserrno == 0); 1808 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1809 1810 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1811 CU_ASSERT(g_bserrno == 0); 1812 g_bs = NULL; 1813 1814 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1815 super_block->crc = 0; 1816 dev = init_dev(); 1817 1818 g_scheduler_delay = true; 1819 /* Load an existing blob store */ 1820 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1821 1822 CU_ASSERT(g_bserrno == -EILSEQ); 1823 _bs_flush_scheduler(); 1824 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1825 1826 g_scheduler_delay = false; 1827 } 1828 1829 /* For blob dirty shutdown test case we do the following sub-test cases: 1830 * 1 Initialize new blob store and create 1 blob with some xattrs, then we 1831 * dirty shutdown and reload the blob store and verify the xattrs. 1832 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 1833 * reload the blob store and verify the clusters number. 1834 * 3 Create the second blob and then dirty shutdown, reload the blob store 1835 * and verify the second blob. 1836 * 4 Delete the second blob and then dirty shutdown, reload teh blob store 1837 * and verify the second blob is invalid. 1838 * 5 Create the second blob again and also create the third blob, modify the 1839 * md of second blob which makes the md invalid, and then dirty shutdown, 1840 * reload the blob store verify the second blob, it should invalid and also 1841 * verify the third blob, it should correct. 1842 */ 1843 static void 1844 blob_dirty_shutdown(void) 1845 { 1846 int rc; 1847 int index; 1848 struct spdk_bs_dev *dev; 1849 spdk_blob_id blobid1, blobid2, blobid3; 1850 struct spdk_blob *blob; 1851 uint64_t length; 1852 const void *value; 1853 size_t value_len; 1854 uint32_t page_num; 1855 struct spdk_blob_md_page *page; 1856 struct spdk_bs_opts opts; 1857 1858 dev = init_dev(); 1859 spdk_bs_opts_init(&opts); 1860 /* Initialize a new blob store */ 1861 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1862 CU_ASSERT(g_bserrno == 0); 1863 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1864 1865 /* Create first blob */ 1866 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1867 CU_ASSERT(g_bserrno == 0); 1868 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1869 blobid1 = g_blobid; 1870 1871 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1872 CU_ASSERT(g_bserrno == 0); 1873 CU_ASSERT(g_blob != NULL); 1874 blob = g_blob; 1875 1876 /* Set some xattrs */ 1877 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1878 CU_ASSERT(rc == 0); 1879 1880 length = 2345; 1881 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1882 CU_ASSERT(rc == 0); 1883 1884 /* Resize the blob */ 1885 rc = spdk_blob_resize(blob, 10); 1886 CU_ASSERT(rc == 0); 1887 1888 spdk_blob_close(blob, blob_op_complete, NULL); 1889 blob = NULL; 1890 g_blob = NULL; 1891 g_blobid = SPDK_BLOBID_INVALID; 1892 1893 /* Dirty shutdown */ 1894 _spdk_bs_free(g_bs); 1895 1896 /* reload blobstore */ 1897 dev = init_dev(); 1898 spdk_bs_opts_init(&opts); 1899 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1900 CU_ASSERT(g_bserrno == 0); 1901 1902 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1903 CU_ASSERT(g_bserrno == 0); 1904 CU_ASSERT(g_blob != NULL); 1905 blob = g_blob; 1906 1907 /* Get the xattrs */ 1908 value = NULL; 1909 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1910 CU_ASSERT(rc == 0); 1911 SPDK_CU_ASSERT_FATAL(value != NULL); 1912 CU_ASSERT(*(uint64_t *)value == length); 1913 CU_ASSERT(value_len == 8); 1914 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1915 1916 /* Resize the blob */ 1917 rc = spdk_blob_resize(blob, 20); 1918 CU_ASSERT(rc == 0); 1919 1920 spdk_blob_close(blob, blob_op_complete, NULL); 1921 CU_ASSERT(g_bserrno == 0); 1922 blob = NULL; 1923 g_blob = NULL; 1924 g_blobid = SPDK_BLOBID_INVALID; 1925 1926 /* Dirty shutdown */ 1927 _spdk_bs_free(g_bs); 1928 1929 /* reload the blobstore */ 1930 dev = init_dev(); 1931 spdk_bs_opts_init(&opts); 1932 /* Load an existing blob store */ 1933 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1934 CU_ASSERT(g_bserrno == 0); 1935 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1936 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1937 CU_ASSERT(g_bserrno == 0); 1938 CU_ASSERT(g_blob != NULL); 1939 blob = g_blob; 1940 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 1941 1942 spdk_blob_close(blob, blob_op_complete, NULL); 1943 CU_ASSERT(g_bserrno == 0); 1944 blob = NULL; 1945 g_blob = NULL; 1946 g_blobid = SPDK_BLOBID_INVALID; 1947 1948 /* Create second blob */ 1949 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1950 CU_ASSERT(g_bserrno == 0); 1951 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1952 blobid2 = g_blobid; 1953 1954 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1955 CU_ASSERT(g_bserrno == 0); 1956 CU_ASSERT(g_blob != NULL); 1957 blob = g_blob; 1958 1959 /* Set some xattrs */ 1960 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 1961 CU_ASSERT(rc == 0); 1962 1963 length = 5432; 1964 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1965 CU_ASSERT(rc == 0); 1966 1967 /* Resize the blob */ 1968 rc = spdk_blob_resize(blob, 10); 1969 CU_ASSERT(rc == 0); 1970 1971 spdk_blob_close(blob, blob_op_complete, NULL); 1972 blob = NULL; 1973 g_blob = NULL; 1974 g_blobid = SPDK_BLOBID_INVALID; 1975 1976 /* Dirty shutdown */ 1977 _spdk_bs_free(g_bs); 1978 1979 /* reload the blobstore */ 1980 dev = init_dev(); 1981 spdk_bs_opts_init(&opts); 1982 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1983 CU_ASSERT(g_bserrno == 0); 1984 1985 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1986 CU_ASSERT(g_bserrno == 0); 1987 CU_ASSERT(g_blob != NULL); 1988 blob = g_blob; 1989 1990 /* Get the xattrs */ 1991 value = NULL; 1992 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1993 CU_ASSERT(rc == 0); 1994 SPDK_CU_ASSERT_FATAL(value != NULL); 1995 CU_ASSERT(*(uint64_t *)value == length); 1996 CU_ASSERT(value_len == 8); 1997 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1998 1999 spdk_blob_close(blob, blob_op_complete, NULL); 2000 CU_ASSERT(g_bserrno == 0); 2001 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 2002 CU_ASSERT(g_bserrno == 0); 2003 2004 /* Dirty shutdown */ 2005 _spdk_bs_free(g_bs); 2006 /* reload the blobstore */ 2007 dev = init_dev(); 2008 spdk_bs_opts_init(&opts); 2009 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2010 CU_ASSERT(g_bserrno == 0); 2011 2012 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2013 CU_ASSERT(g_bserrno != 0); 2014 CU_ASSERT(g_blob == NULL); 2015 2016 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2017 CU_ASSERT(g_bserrno == 0); 2018 CU_ASSERT(g_blob != NULL); 2019 spdk_blob_close(g_blob, blob_op_complete, NULL); 2020 CU_ASSERT(g_bserrno == 0); 2021 2022 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2023 CU_ASSERT(g_bserrno == 0); 2024 g_bs = NULL; 2025 2026 /* reload the blobstore */ 2027 dev = init_dev(); 2028 spdk_bs_opts_init(&opts); 2029 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2030 CU_ASSERT(g_bserrno == 0); 2031 2032 /* Create second blob */ 2033 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2034 CU_ASSERT(g_bserrno == 0); 2035 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2036 blobid2 = g_blobid; 2037 2038 /* Create third blob */ 2039 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2040 CU_ASSERT(g_bserrno == 0); 2041 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2042 blobid3 = g_blobid; 2043 2044 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2045 CU_ASSERT(g_bserrno == 0); 2046 CU_ASSERT(g_blob != NULL); 2047 blob = g_blob; 2048 2049 /* Set some xattrs for second blob */ 2050 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2051 CU_ASSERT(rc == 0); 2052 2053 length = 5432; 2054 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2055 CU_ASSERT(rc == 0); 2056 2057 spdk_blob_close(blob, blob_op_complete, NULL); 2058 blob = NULL; 2059 g_blob = NULL; 2060 g_blobid = SPDK_BLOBID_INVALID; 2061 2062 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2063 CU_ASSERT(g_bserrno == 0); 2064 CU_ASSERT(g_blob != NULL); 2065 blob = g_blob; 2066 2067 /* Set some xattrs for third blob */ 2068 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 2069 CU_ASSERT(rc == 0); 2070 2071 length = 5432; 2072 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2073 CU_ASSERT(rc == 0); 2074 2075 spdk_blob_close(blob, blob_op_complete, NULL); 2076 blob = NULL; 2077 g_blob = NULL; 2078 g_blobid = SPDK_BLOBID_INVALID; 2079 2080 /* Mark second blob as invalid */ 2081 page_num = _spdk_bs_blobid_to_page(blobid2); 2082 2083 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 2084 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2085 page->sequence_num = 1; 2086 page->crc = _spdk_blob_md_page_calc_crc(page); 2087 2088 /* Dirty shutdown */ 2089 _spdk_bs_free(g_bs); 2090 /* reload the blobstore */ 2091 dev = init_dev(); 2092 spdk_bs_opts_init(&opts); 2093 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2094 CU_ASSERT(g_bserrno == 0); 2095 2096 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2097 CU_ASSERT(g_bserrno != 0); 2098 CU_ASSERT(g_blob == NULL); 2099 2100 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2101 CU_ASSERT(g_bserrno == 0); 2102 CU_ASSERT(g_blob != NULL); 2103 blob = g_blob; 2104 2105 spdk_blob_close(blob, blob_op_complete, NULL); 2106 blob = NULL; 2107 g_blob = NULL; 2108 g_blobid = SPDK_BLOBID_INVALID; 2109 2110 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2111 CU_ASSERT(g_bserrno == 0); 2112 g_bs = NULL; 2113 } 2114 2115 static void 2116 blob_flags(void) 2117 { 2118 struct spdk_bs_dev *dev; 2119 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 2120 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 2121 struct spdk_bs_opts opts; 2122 2123 dev = init_dev(); 2124 spdk_bs_opts_init(&opts); 2125 2126 /* Initialize a new blob store */ 2127 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2128 CU_ASSERT(g_bserrno == 0); 2129 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2130 2131 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 2132 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2133 CU_ASSERT(g_bserrno == 0); 2134 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2135 blobid_invalid = g_blobid; 2136 2137 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2138 CU_ASSERT(g_bserrno == 0); 2139 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2140 blobid_data_ro = g_blobid; 2141 2142 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2143 CU_ASSERT(g_bserrno == 0); 2144 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2145 blobid_md_ro = g_blobid; 2146 2147 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2148 CU_ASSERT(g_bserrno == 0); 2149 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2150 blob_invalid = g_blob; 2151 2152 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2153 CU_ASSERT(g_bserrno == 0); 2154 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2155 blob_data_ro = g_blob; 2156 2157 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2158 CU_ASSERT(g_bserrno == 0); 2159 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2160 blob_md_ro = g_blob; 2161 2162 __blob_to_data(blob_invalid)->invalid_flags = (1ULL << 63); 2163 __blob_to_data(blob_invalid)->state = SPDK_BLOB_STATE_DIRTY; 2164 __blob_to_data(blob_data_ro)->data_ro_flags = (1ULL << 62); 2165 __blob_to_data(blob_data_ro)->state = SPDK_BLOB_STATE_DIRTY; 2166 __blob_to_data(blob_md_ro)->md_ro_flags = (1ULL << 61); 2167 __blob_to_data(blob_md_ro)->state = SPDK_BLOB_STATE_DIRTY; 2168 2169 g_bserrno = -1; 2170 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 2171 CU_ASSERT(g_bserrno == 0); 2172 g_bserrno = -1; 2173 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 2174 CU_ASSERT(g_bserrno == 0); 2175 g_bserrno = -1; 2176 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2177 CU_ASSERT(g_bserrno == 0); 2178 2179 g_bserrno = -1; 2180 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 2181 CU_ASSERT(g_bserrno == 0); 2182 blob_invalid = NULL; 2183 g_bserrno = -1; 2184 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2185 CU_ASSERT(g_bserrno == 0); 2186 blob_data_ro = NULL; 2187 g_bserrno = -1; 2188 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2189 CU_ASSERT(g_bserrno == 0); 2190 blob_md_ro = NULL; 2191 2192 g_blob = NULL; 2193 g_blobid = SPDK_BLOBID_INVALID; 2194 2195 /* Unload the blob store */ 2196 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2197 CU_ASSERT(g_bserrno == 0); 2198 g_bs = NULL; 2199 2200 /* Load an existing blob store */ 2201 dev = init_dev(); 2202 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2203 CU_ASSERT(g_bserrno == 0); 2204 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2205 2206 g_blob = NULL; 2207 g_bserrno = 0; 2208 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2209 CU_ASSERT(g_bserrno != 0); 2210 CU_ASSERT(g_blob == NULL); 2211 2212 g_blob = NULL; 2213 g_bserrno = -1; 2214 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2215 CU_ASSERT(g_bserrno == 0); 2216 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2217 blob_data_ro = g_blob; 2218 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 2219 CU_ASSERT(__blob_to_data(blob_data_ro)->data_ro == true); 2220 CU_ASSERT(__blob_to_data(blob_data_ro)->md_ro == true); 2221 2222 g_blob = NULL; 2223 g_bserrno = -1; 2224 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2225 CU_ASSERT(g_bserrno == 0); 2226 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2227 blob_md_ro = g_blob; 2228 CU_ASSERT(__blob_to_data(blob_md_ro)->data_ro == false); 2229 CU_ASSERT(__blob_to_data(blob_md_ro)->md_ro == true); 2230 2231 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2232 CU_ASSERT(g_bserrno == 0); 2233 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2234 CU_ASSERT(g_bserrno == 0); 2235 2236 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2237 CU_ASSERT(g_bserrno == 0); 2238 } 2239 2240 static void 2241 bs_version(void) 2242 { 2243 struct spdk_bs_super_block *super; 2244 struct spdk_bs_dev *dev; 2245 struct spdk_bs_opts opts; 2246 spdk_blob_id blobid; 2247 2248 dev = init_dev(); 2249 spdk_bs_opts_init(&opts); 2250 2251 /* Initialize a new blob store */ 2252 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2253 CU_ASSERT(g_bserrno == 0); 2254 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2255 2256 /* Unload the blob store */ 2257 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2258 CU_ASSERT(g_bserrno == 0); 2259 g_bs = NULL; 2260 2261 /* 2262 * Change the bs version on disk. This will allow us to 2263 * test that the version does not get modified automatically 2264 * when loading and unloading the blobstore. 2265 */ 2266 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 2267 CU_ASSERT(super->version == SPDK_BS_VERSION); 2268 CU_ASSERT(super->clean == 1); 2269 super->version = 2; 2270 /* 2271 * Version 2 metadata does not have a used blobid mask, so clear 2272 * those fields in the super block and zero the corresponding 2273 * region on "disk". We will use this to ensure blob IDs are 2274 * correctly reconstructed. 2275 */ 2276 memset(&g_dev_buffer[super->used_blobid_mask_start * PAGE_SIZE], 0, 2277 super->used_blobid_mask_len * PAGE_SIZE); 2278 super->used_blobid_mask_start = 0; 2279 super->used_blobid_mask_len = 0; 2280 super->crc = _spdk_blob_md_page_calc_crc(super); 2281 2282 /* Load an existing blob store */ 2283 dev = init_dev(); 2284 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2285 CU_ASSERT(g_bserrno == 0); 2286 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2287 CU_ASSERT(super->clean == 0); 2288 2289 /* 2290 * Create a blob - just to make sure that when we unload it 2291 * results in writing the super block (since metadata pages 2292 * were allocated. 2293 */ 2294 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2295 CU_ASSERT(g_bserrno == 0); 2296 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2297 blobid = g_blobid; 2298 2299 /* Unload the blob store */ 2300 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2301 CU_ASSERT(g_bserrno == 0); 2302 g_bs = NULL; 2303 CU_ASSERT(super->version == 2); 2304 CU_ASSERT(super->used_blobid_mask_start == 0); 2305 CU_ASSERT(super->used_blobid_mask_len == 0); 2306 2307 dev = init_dev(); 2308 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2309 CU_ASSERT(g_bserrno == 0); 2310 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2311 2312 g_blob = NULL; 2313 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2314 CU_ASSERT(g_bserrno == 0); 2315 CU_ASSERT(g_blob != NULL); 2316 2317 spdk_blob_close(g_blob, blob_op_complete, NULL); 2318 CU_ASSERT(g_bserrno == 0); 2319 2320 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2321 CU_ASSERT(g_bserrno == 0); 2322 g_bs = NULL; 2323 CU_ASSERT(super->version == 2); 2324 CU_ASSERT(super->used_blobid_mask_start == 0); 2325 CU_ASSERT(super->used_blobid_mask_len == 0); 2326 } 2327 2328 static void 2329 _get_xattr_value(void *arg, const char *name, 2330 const void **value, size_t *value_len) 2331 { 2332 uint64_t i; 2333 2334 SPDK_CU_ASSERT_FATAL(value_len != NULL); 2335 SPDK_CU_ASSERT_FATAL(value != NULL); 2336 CU_ASSERT(arg == &g_ctx) 2337 2338 for (i = 0; i < sizeof(g_xattr_names); i++) { 2339 if (!strcmp(name, g_xattr_names[i])) { 2340 *value_len = strlen(g_xattr_values[i]); 2341 *value = g_xattr_values[i]; 2342 break; 2343 } 2344 } 2345 } 2346 2347 static void 2348 _get_xattr_value_null(void *arg, const char *name, 2349 const void **value, size_t *value_len) 2350 { 2351 SPDK_CU_ASSERT_FATAL(value_len != NULL); 2352 SPDK_CU_ASSERT_FATAL(value != NULL); 2353 CU_ASSERT(arg == NULL) 2354 2355 *value_len = 0; 2356 *value = NULL; 2357 } 2358 2359 static void 2360 blob_set_xattrs(void) 2361 { 2362 struct spdk_blob_store *bs; 2363 struct spdk_bs_dev *dev; 2364 struct spdk_blob *blob; 2365 struct spdk_blob_opts opts; 2366 spdk_blob_id blobid; 2367 const void *value; 2368 size_t value_len; 2369 int rc; 2370 2371 dev = init_dev(); 2372 2373 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2374 CU_ASSERT(g_bserrno == 0); 2375 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2376 bs = g_bs; 2377 2378 /* Create blob with extra attributes */ 2379 spdk_blob_opts_init(&opts); 2380 2381 opts.xattr_names = g_xattr_names; 2382 opts.get_xattr_value = _get_xattr_value; 2383 opts.xattr_count = 3; 2384 opts.xattr_ctx = &g_ctx; 2385 2386 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2387 CU_ASSERT(g_bserrno == 0); 2388 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2389 blobid = g_blobid; 2390 2391 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2392 CU_ASSERT(g_bserrno == 0); 2393 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2394 blob = g_blob; 2395 2396 /* Get the xattrs */ 2397 value = NULL; 2398 2399 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 2400 CU_ASSERT(rc == 0); 2401 SPDK_CU_ASSERT_FATAL(value != NULL); 2402 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 2403 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 2404 2405 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 2406 CU_ASSERT(rc == 0); 2407 SPDK_CU_ASSERT_FATAL(value != NULL); 2408 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 2409 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 2410 2411 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 2412 CU_ASSERT(rc == 0); 2413 SPDK_CU_ASSERT_FATAL(value != NULL); 2414 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 2415 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 2416 2417 /* Try to get non existing attribute */ 2418 2419 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2420 CU_ASSERT(rc == -ENOENT); 2421 2422 spdk_blob_close(blob, blob_op_complete, NULL); 2423 CU_ASSERT(g_bserrno == 0); 2424 blob = NULL; 2425 g_blob = NULL; 2426 g_blobid = SPDK_BLOBID_INVALID; 2427 2428 /* NULL callback */ 2429 spdk_blob_opts_init(&opts); 2430 opts.xattr_names = g_xattr_names; 2431 opts.get_xattr_value = NULL; 2432 opts.xattr_count = 1; 2433 opts.xattr_ctx = &g_ctx; 2434 2435 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2436 CU_ASSERT(g_bserrno == -EINVAL); 2437 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2438 2439 /* NULL values */ 2440 spdk_blob_opts_init(&opts); 2441 opts.xattr_names = g_xattr_names; 2442 opts.get_xattr_value = _get_xattr_value_null; 2443 opts.xattr_count = 1; 2444 opts.xattr_ctx = NULL; 2445 2446 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2447 CU_ASSERT(g_bserrno == -EINVAL); 2448 2449 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2450 CU_ASSERT(g_bserrno == 0); 2451 g_bs = NULL; 2452 2453 } 2454 2455 int main(int argc, char **argv) 2456 { 2457 CU_pSuite suite = NULL; 2458 unsigned int num_failures; 2459 2460 if (CU_initialize_registry() != CUE_SUCCESS) { 2461 return CU_get_error(); 2462 } 2463 2464 suite = CU_add_suite("blob", NULL, NULL); 2465 if (suite == NULL) { 2466 CU_cleanup_registry(); 2467 return CU_get_error(); 2468 } 2469 2470 if ( 2471 CU_add_test(suite, "blob_init", blob_init) == NULL || 2472 CU_add_test(suite, "blob_open", blob_open) == NULL || 2473 CU_add_test(suite, "blob_create", blob_create) == NULL || 2474 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 2475 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 2476 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 2477 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 2478 CU_add_test(suite, "blob_super", blob_super) == NULL || 2479 CU_add_test(suite, "blob_write", blob_write) == NULL || 2480 CU_add_test(suite, "blob_read", blob_read) == NULL || 2481 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 2482 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 2483 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 2484 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 2485 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 2486 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 2487 CU_add_test(suite, "bs_load", bs_load) == NULL || 2488 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 2489 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 2490 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 2491 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 2492 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 2493 CU_add_test(suite, "bs_type", bs_type) == NULL || 2494 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 2495 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 2496 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 2497 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 2498 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 2499 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 2500 CU_add_test(suite, "bs_version", bs_version) == NULL || 2501 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL 2502 ) { 2503 CU_cleanup_registry(); 2504 return CU_get_error(); 2505 } 2506 2507 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 2508 spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 2509 CU_basic_set_mode(CU_BRM_VERBOSE); 2510 CU_basic_run_tests(); 2511 num_failures = CU_get_number_of_failures(); 2512 CU_cleanup_registry(); 2513 spdk_free_thread(); 2514 free(g_dev_buffer); 2515 return num_failures; 2516 } 2517